I'm having trouble setting the 'accountexpires' and wondered if anyone knows a way around it, I believe it's because I have a 18 digit number. I have a form where someone sets a date, I need to set the account to expire then, if I provide the number as a hardcoded string it works, but I cannot convert the finished calculation to a string. Anyone know any way around this? thanks.
<?php
$currentTimeUnix = 1442383989; //this will vary depending on user's input
$secondsBetween1601and1970 = 11644473600;
$timesAdded = $currentTimeUnix + $secondsBetween1601and1970;// comes to 13086857589
$nanoseconds = $timesAdded * 10000000; //comes to 130868575890000000
echo $nanoseconds; //displays 1.3086857589E+017
echo (string)$nanoseconds; //displays 1.3086857589E+017
echo strval($nanoseconds); //displays 1.3086857589E+017
?>
PHP is kind of bad with large numbers but sprintf can help. try:
echo sprintf( '%018.0f', $nanoseconds );
-> 130868575890000000
Alternatively you change the "precision" setting where precision is described:
precision integer
The number of significant digits displayed in floating point numbers.
ini_set("precision",20);
echo $nanoseconds;
-> 130868575890000000
Thanks for this. Been testing true out the net but nothing worked until i stumbled on this solution:
$expiredate = strtotime($values["expires"]);
$currentTimeUnix = $expiredate;
$secondsBetween1601and1970 = 11644473600;
$timesAdded = $currentTimeUnix + $secondsBetween1601and1970;
$nanoseconds = $timesAdded * 10000000;
$expires = sprintf('%018.0f',$nanoseconds);
Related
As an example I have code similar to this:
$r1 = 7.39999999999999;
$r2 = 10000;
echo bcmul($r1,$r2,100);
//returns 74000.0
echo ($r1*$r2);
//returns 74000.0
I am wanting it to return 73999.9999999999 rather than rounding it off.
Is there a formula or function to do this?
The doc http://php.net/manual/de/function.bcmul.php says:
left_operand: The left operand, as a string.
right_operand: The right operand, as a string.
So use strings instead:
$r1 = "7.39999999999999";
$r2 = "10000";
echo bcmul($r1,$r2,100);
works.
Or if you have these varibales from somewhere cast them (via (string) ) to string. Maybe at this step you could encounter some roundings already...
I'm not a php person, but a quick Google suggests you may want the
$number_format()
function and specify the $decimals parameter. See this link
I've looked at php-big numbers, BC Math, and GMP for dealing with very big numbers in php. But none seem to have a function equivilent to php's log(). For example I want to do this:
$result = log($bigNumber, 2);
Would anyone know of an alternate way to get the log base 2 of a arbitray precision point number in php? Maybe Ive missed a function, or library, or formula.
edit: php-bignumbers seems to have a log base 10 function only log10()
In general if you want to implement your high precision log own calculation, I'd suggest 1st use the basic features of logarithm:
log_a(x) = log_b(x) / log_b(a) |=> thus you can recalulate logarith to any base
log(x*y) = log(x) + log(y)
log(a**n) = n*log(a)
where log_a(x) - meaning logarithm to the base a of x; log means natural logarithm
So log(1000000000000000000000.123) = 21*log(1.000000000000000000000123)
and for high precision of log(1+x)
use algorithm referenced at
http://en.wikipedia.org/wiki/Natural_logarithm#High_precision
One solution combining the suggestions so far would be to use this formula:
log2($num) = log10($num) / log10(2)
in conjunction with php-big numbers since it has a pre-made log10 function.
eg, after installing the php-big numbers library, use:
$log2 = log10($bigNum) / log10(2);
Personally I've decided to use different math/logic so as to not need the log function, and just using bcmath for the big numbers.
One of the great things about base 2 is that counting and shifting become part of the tool set.
So one way to get a 'log2' of a number is to convert it to a binary string and count the bits.
You can accomplish this equivalently by dividing by 2 in a loop. But it seems to me that counting would be more efficient.
gmp_scan0 and gmp_scan1 can be used if you are counting from the right. But you'd have to somehow convert the mixed bits to all ones and zeroes.
But using gmp_strval(num, 2), you can produce a string and do a strpos on it.
if the whole value is being converted, you can do a (strlen - 1) on it.
Obviously this only works when you want an integer log.
I've had a very similar problem just recently.. and so I just scaled the number considerably in order to use the inbuild log to find the fractional part.. (I prefere the log10 for some reason.. don't ask... people are strange, me too)
I hope this is selfexplanatory enough..
it returns a float value (since that's what I needed)
function gmp_log($num, $base=10, $full=true)
{
if($base == 10)
$string = gmp_strval($num);
else
$string = gmp_strval($num,$base);
$intpart = strlen($string)-1;
if(!$full)
return $intpart;
if($base ==10)
{
$string = substr_replace($string, ".", 1, 0);
$number = floatval($string);
$lg = $intpart + log10($number);
return $lg;
}
else
{
$string = gmp_strval($num);
$intpart = strlen($string)-1;
$string = substr_replace($string, ".", 1, 0);
$number = floatval($string);
$lg = $intpart + log10($number);
$lb = $lg / log10($base);
return $lb;
}
}
it's quick, it's dirty... but it works well enough to get the log of some RSA sized integers ;)
usage is straight forward as well
$N = gmp_init("11002930366353704069");
echo gmp_log($N,10)."\n";
echo gmp_log($N,10, false)."\n";
echo gmp_log($N,2)."\n";
echo gmp_log($N,16)."\n";
returns
19.041508364472
19
63.254521604973
15.813630401243
this might be a stupid question but I have searched again and again without finding any results.
So, what I want is to show all the decimal places of a number without knowing how many decimal places it will have. Take a look at this small code:
$arrayTest = array(0.123456789, 0.0123456789);
foreach($arrayTest as $output){
$newNumber = $output/1000;
echo $newNumber;
echo "<br>";
}
It gives this output:
0.000123456789
1.23456789E-5
Now, I tried using 'number_format', but I don't think that is a good solution. It determines an exact amount of decimal places, and I do not know the amount of decimal places for every number. Take a look at the below code:
$arrayTest = array(0.123456789, 0.0123456789);
foreach($arrayTest as $output){
$newNumber = $output/1000;
echo number_format($newNumber,13);
echo "<br>";
}
It gives this output:
0.0001234567890
0.0000123456789
Now, as you can see there is an excess 0 in the first number, because number_format forces it to have 13 decimal places.
I would really love some guidance on how to get around this problem. Is there a setting in PHP.ini which determines the amount of decimals?
Thank you very much in advance!
(and feel free to ask if you have any further questions)
It is "impossible" to answer this question properly - because a binary float representation of a decimal number is approximate: "What every computer scientist should know about floating point"
The closest you can come is write yourself a routine that looks at a decimal representation of a number, and compares it to the "exact" value; once the difference becomes "small enough for your purpose", you stop adding more digits.
This routine could then return the "correct number of digits" as a string.
Example:
<?php
$a = 1.234567890;
$b = 0.123456789;
echo returnString($a)."\n";
echo returnString($b)."\n";
function returnString($a) {
// return the value $a as a string
// with enough digits to be "accurate" - that is, the value returned
// matches the value given to 1E-10
// there is a limit of 10 digits to cope with unexpected inputs
// and prevent an infinite loop
$conv_a = 0;
$digits=0;
while(abs($a - $conv_a) > 1e-10) {
$digits = $digits + 1;
$conv_a = 0 + number_format($a, $digits);
if($digits > 10) $conv_a = $a;
}
return $conv_a;
}
?>
Which produces
1.23456789
0.123456789
In the above code I arbitrarily assumed that being right to within 1E-10 was good enough. Obviously you can change this condition to whatever is appropriate for the numbers you encounter - and you could even make it an optional argument of your function.
Play with it - ask questions if this is not clear.
I have a big time trying to either convert a string into a integer or multiply two integers. I can't convert the string into integer because it's resulting me into a boolean (when I'm using var_dump). I can convert the other integer in string, but I'm unable to multiply it.
I have this:
<? $fees=$commerce->cart->get_total();
$payfee = str_replace(' €', '', $fees);
$payfee = str_replace(',','', $payfee); //this is the string
$fee = 0.025;
$paypal = $payfee * $fee; //this thing is not working
?>
I tried converting the payfee in integer, but still can't make it work. I did something like this before and worked well, but not this time.
Any help will be appreciated.
P.S Thank you to the whole stackoverflow.com community which helped me many times before.
OP is running WooCommerce, and his $commerce->cart->get_total();
function responds output such as <span class="amount">560 €</span> (560 €)
and he's asking how to convert this to a number so he can get a fee
(2.5 %) from the amount.
First of all, the problem here is that the get_total() function responds with a string.
The correct way to fix this string would be a simple example such as
<?php
$totalAmountString = $commerce->cart->get_total(); //<span class="amount">560 €</span>
$totalAmountString = strip_tags($totalAmountString); //get rid of the span - we're left with "560 €"
$totalAmountString = str_replace(array(" €", ","), "", $totalAmountString);
$totalAmountFloat = (float)$totalAmountString;
$fee = 0.025;
$feeForThisAmount = $totalAmountFloat * $fee;
var_dump($feeForThisAmount);
$totalAmountWithFee = $totalAmountFloat + $feeForThisAmount;
var_dump($totalAmountWithFee);
?>
However, according to the Woo Commerce API Documentation you should be able to use $commerce->cart->total to get a float of the number, so a solution that might also work (again, I know nothing about WooCommerce), would be the following:
<?php
$totalAmountFloat = $commerce->cart->total;
$fee = 0.025;
$feeForThisAmount = $totalAmountFloat * $fee;
var_dump($feeForThisAmount);
$totalAmountWithFee = $totalAmountFloat + $feeForThisAmount;
var_dump($totalAmountWithFee);
?>
Edit
According to your latest data dump, the problem is that you're using
$paypal_fees=$woocommerce->cart->get_total() * 0.025;
where you should be using
$paypal_fees=$woocommerce->cart->total * 0.025;
as ->get_total() receives a string, and ->total receives a float.
try this
$integer =(int)$string;
LIve example
with var_dump() its correct
check this link
Use type casting like
$integer = (int)$myString;
then you can convert it to an integer,and its become easy to multiply
Use intval() function to covert string to integer
intval
From your elementary school technique based algorithm is posted here . You need not to convert string to integer in this case
I am storing sms received from twilio in a database so I can use them later. When I did this in the sandbox it worked. However when I upgraded to a regular phone number the number received is the same as was sent to, but +1 (or for xxxxxxxxxx where the x's are the original number, it looks more like 1xxxxxxxxxx+)
I therefore changed the mysql_query to the following: but it is still not working. What can be done to recognize that this is the original phone number?
<?php
$starttime = time();
$number = $_POST['number'];
$number1 = "1" . $number;
$number2 = $number . "1";
$number3 = "+1" . $number;
$number4 = $number . "+1";
$number5 = "+" . $number . "1";
$number6 = "1" . $number . "+";
$number7 = $number."1+";
$received = mysql_query("SELECT * FROM sms_received
WHERE (responder='$number' OR responder='$number1'
OR responder='$number2' OR responder='$number3'
OR responder='$number4' OR responder='$number5'
OR responder='$number6' OR responder='$number6')
AND (body='y' OR body='yes' OR body='Y' OR body='Yes' OR 'yea' OR 'Yea')
AND timestamp BETWEEN ".date('Y-m-d H:i:s', strtotime($starttime))." AND NOW()");
?>
But still, nothing is being received. Any ideas how else I can check whether an sms has been received from the user? I can see in the database that it's there... but the mysql isn't finding it. It worked before, when the number sent was identical to the number received from, but with the added +1 it screws it up. (the code before just had WHERE responder = '$number' and it worked, but the additional variables didn't help it).
Does this code have too many OR's? Is that even a problem?
UPDATE:
Thanks, here is the function I'm using to strip the number down to xxxxxxxxxx format, before saving it to the database:
function checkPhone($responder){
$items = Array('/\ /', '/\+/', '/\-/', '/\./', '/\,/', '/\(/', '/\)/', '/[a-zA-Z]/');
$clean = preg_replace($items, '', $responder);
if (substr($clean, 0, 1) == "1") {
return substr($clean, 1, 10);
}
else {
return substr($clean, 0, 10);
}
}
$number = checkPhone($responder);
Twilio returns numbers in a format called E.164, which is an internationally recognized standard for phone number formatting.
In general, it's best practice to standardize the number to E164 BEFORE you store it in the database. That way you don't have to worry about storing different data with two different copies of the same number - eg 925-555-1234 and (925) 5551234.
Google has a libphonenumber library that will convert numbers for you. It works with Javascript, C++, Java, and Python.
If you are using PHP, and only using US/Canadian numbers, you can write a function to normalize phone numbers, that does something like the following:
- Strip out all non number characters from the phone number
(parentheses, dashes, spaces) - you can use a function like preg_replace
- if the phone number begins with a +1, do nothing
- if the phone number begins with a 1, add a +
- else, add a +1 to the beginning of the number.
- finally, store it in the database.
I hope that helps - please let me know if you have more questions.
Kevin
Your last or is redundantly $number6, it should be $number7.
Aside from that, you can do a few different things, such as in:
responder in ('$number', '$number1', '$number2', '$number3', '$number4', '$number5', '$number6', '$number7')
Or something like this:
responder like '%$number%'
Use a regular expression.
preg_match_all("{[0-9]+}",$number,$m);
$norm_num="+".implode($m[0]);
if(strlen($norm_num)<6)
exit('Too short!');
mysql_query("SELECT * FROM sms_received
WHERE responder='%$norm_num%'
AND body IN ('y','yes','Y','Yes','yea','Yea')
AND timestamp BETWEEN ".date('Y-m-d H:i:s', strtotime($starttime))." AND NOW()");