php currency take - php

I need to know how to take
10.25 and turn it to 1025
basically it needs to remove full stop from any number for e.g.
1500.25 it should be 150025

$number = str_replace('.','',$number);

if the currency is a float: multiply with 100 (and cast the result to int).
$currency = 10.25;
$number = (int)($currency * 100); //1025
note that this solution will only get the first two decimals saved - if you have a number like 10.123, the 3 will simply be cut off without rounding.

Floating-point arithmetic is by it's definition not exact. Therefore it's worthwhile to NOT cast the value to a float if it's a string, and avoid casting it into a string if it's a float.
Here's a function which takes care to check the value type:
function toCents($value) {
// Strings with a dot is specially handled
// so they won't be converted to float
if (is_string($value) && strpos($value, '.') !== false) {
list($integer, $decimals) = explode('.', $value);
$decimals = (int) substr($decimals . '00', 0, 2);
return ((int) $integer) * 100 + $decimals;
// float values are rounded to avoid errors when a value
// like ".10" is saved as ".099"
} elseif (is_float($value) {
return round($value * 100);
// Other values are strings or integers, which are cast
// to int and multiplied directly.
} else {
return ((int) $value) * 100;
}
}

if you want replace one character only, use strtr instead str_replace
$number = str_replace('.','',$number);
and
$number = strtr($number, array('.', ''));
same output but strtr is better.

Related

PHP round to integer

I want to round a number and I need a proper integer because I want to use it as an array key. The first "solution" that comes to mind is:
$key = (int)round($number)
However, I am unsure if this will always work. As far as I know (int) just truncates any decimals and since round($number) returns a float with theoretically limited precision, is it possible that round($number) returns something like 7.999999... and then $key is 7 instead of 8?
If this problem actually exists (I don't know how to test for it), how can it be solved? Maybe:
$key = (int)(round($number) + 0.0000000000000000001) // number of zeros chosen arbitrarily
Is there a better solution than this?
To round floats properly, you can use:
ceil($number): round up
round($number, 0): round to the nearest integer
floor($number): round down
Those functions return float, but from Niet the Dark Absol comment: "Integers stored within floats are always accurate, up to around 2^51, which is much more than can be stored in an int anyway."
round(), without a precision set always rounds to the nearest whole number. By default, round rounds to zero decimal places.
So:
$int = 8.998988776636;
round($int) //Will always be 9
$int = 8.344473773737377474;
round($int) //will always be 8
So, if your goal is to use this as a key for an array, this should be fine.
You can, of course, use modes and precision to specify exactly how you want round() to behave. See this.
UPDATE
You might actually be more interested in intval:
echo intval(round(4.7)); //returns int 5
echo intval(round(4.3)); // returns int 4
What about simply adding 1/2 before casting to an int?
eg:
$int = (int) ($float + 0.5);
This should give a predictable result.
Integers stored within floats are always accurate, up to around 253, which is much more than can be stored in an int anyway. I am worrying over nothing.
For My Case, I have to make whole number by float or decimal type
number. By these way i solved my problem. Hope It works For You.
$value1 = "46.2";
$value2 = "46.8";
// If we print by round()
echo round( $value1 ); //return float 46.0
echo round( $value2 ); //return float 47.0
// To Get the integer value
echo intval(round( $value1 )); // return int 46
echo intval(round( $value2 )); // return int 47
My solution:
function money_round(float $val, int $precision = 0): float|int
{
$pow = pow(10, $precision);
$result = (float)(intval((string)($val * $pow)) / $pow);
if (str_contains((string)$result, '.')) {
return (float)(intval((string)($val * $pow)) / $pow);
}
else {
return (int)(intval((string)($val * $pow)) / $pow);
}
}
Round to the nearest integer
$key = round($number, 0);

Remove useless 0 after 3 digits and round after 6 digit

I use the floatval() function to remove useless 0s, but I want to keep at least 3 significant numbers. Like if I have 0.1800000 I want to show 0.180 and if I have 1.8454214 I want to show 1.845421. How can I do a round after 6 digits and remove useless 0s after 3 digits?
$value = 1.80000;
$value = floatval(round($value,6));
echo $value; //I get 1.8
Or if I have
$value = 1.84542146543;
$value = floatval(round($value,6));
echo $value; //I get 1.845421
And this works fine, but not if I've got a lot of 0s.
I always need minimum 3 decimal, but it can be more.
Try with the below code
$value = 1.80000;
$value = floatval(round($value,6));
$valArr = explode('.', $value);
if(isset($valArr[1])){
if(strlen($valArr[1]) < 3){
$valArr[1] = str_pad($valArr[1], 3, "0", STR_PAD_RIGHT);
$value = $valArr[0].'.'.$valArr[1];
}
else{
$value = floatval(round($value,6));
}
}
echo $value;
It will work if you want to print the 0s in your web page.
Use a combination of floor and sprintf to truncate the float to a string with 3 decimal places. Then use max to compare it with the rounded float. PHP will compare the values numerically, returning the first parameter (padded with zeros) if they are numerically the same, only returning the second value if it is numerically greater (ie there is a digit larger than 0 after the third decimal place).
$value = max(
sprintf("%.3f", floor($value * pow(10, 3)) / pow(10, 3)),
round($value, 6));

Generate non-negative random value slightly above or below a number

I need to slightly scramble real numbers in a report. The values are typically between 0 and 1000, with most being small numbers containing decimals with a scale of 2.
Some examples:
32.1
0.10
0.02
0.01
I put together this simple function to scramble the values slightly:
function tickle_int($v)
{
$tickled = $v + (mt_rand(-40, 40) / 100);
if ($tickled==$v)
{
$tickled = tickle_int($v);
}
return $tickled;
}
But I'm finding that the returned value is often negative. If I change the low value of mt_rand to 0, I only get scrambled values that are greater than the original value, reducing randomness.
How could this function be modified to only return a non-negative value that is randomly above or below the passed input?
Edit to add I need to avoid 0. The scrambled value needs to be non-negative and not zero. The kicker is passing .01. I need a way of randomzing that to values such as .009, .02, .011, ect -- while continuing to significantly randomize larger values.
Limit it:
$tickled = $v + ( mt_rand( $v*(-1), 40) / 100 );
try this,
function tickle_int($v)
{
$random = mt_rand(40, 80);
$tickled = $v + (($random - 40) / 100);
if ($tickled==$v)
{
$tickled = tickle_int($v);
}
print_r($tickled);
}
You have to move -40 outside of mt_rand:
function tickle_int($v, $w)
{
$tickled = $v + (mt_rand(0, 2 * $w) - ($v >= $w? $w : $v)) / 100;
if ($tickled==$v)
{
$tickled = tickle_int($v);
}
return $tickled;
}
tickle_int(0.5, 40);
If you don't care too much about the random distribution, then you could simply do
if ($tickled < 0)
{
$tickled = 0;
}
return $tickled;
Otherwise, you need to modify the min parameter passed to mt_rand to be dependent on $v.

Converting to and from CENTS

So I know there have been multiple questions regarding Money and converting to and from cents.
Heck I have even asked another one, but I want to make a slightly different question so I hope there are no duplicates out there.
So I have created a function that takes a Dollar Value and sends it to CENTS.
But I think I have a slight problem with my code and hoping I can get it tweaked a little.
$money4 = "10.0001";
// Converted to cents, as you can see it's slightly off.
$money41 = "1001";
// So when "1001", get's put in the database, and then I return it back as a Money variable.
// We get, "$10.01"... but what I have now is a leak in my amounts... as it rounded up to the second point.
So to do what I have done, I have used to functions I made to do this.
// This essentially gets a DOLLAR figure, or the CENT's Figure if requested.
function stripMoney($value, $position = 0, $returnAs = "")
{
// Does it even have a decimal?
if(isset($value) && strstr($value, ".")) {
// Strip out everything but numbers, decimals and negative
$value = preg_replace("/([^0-9\.\-])/i","",$value);
$decimals = explode(".", $value);
// Return Dollars as default
return ($returnAs == "int" ? (int)$decimals[$position] : $decimals[$position]);
} elseif(isset($value)) {
// If no decimals, lets just return a solid number
$value = preg_replace("/([^0-9\.\-])/i","",$value);
return ($returnAs == "int" ? (int)$value : $value);
}
}
The next function I use is to generate the CENTS or return it back as dollars.
function convertCents($money, $cents = NULL, $toCents = TRUE)
{
if(isset($money)) {
if($toCents == TRUE) {
// Convert dollars to cents
$totalCents = $money * 100;
// If we have any cents, lets add them on as well
if(isset($cents)) {
$centsCount = strlen($cents);
// In case someone inputs, $1.1
// We add a zero to the end of the var to make it accurate
if($centsCount < 2) {
$cents = "{$cents}0";
}
// Add the cents together
$totalCents = $totalCents + $cents;
}
// Return total cents
return $totalCents;
} else {
// Convert cents to dollars
$totalDollars = $money / 100;
return $totalDollars;
}
}
}
And the final function that puts everything together. So we just use 1 function to merge the 2 functions together basically.
function convertMoney($value, $toCents = TRUE) {
if(isset($value) && strstr($value, ".")) {
return convertCents(stripMoney($value, 0), stripMoney($value, 1), $toCents);
} elseif(!empty($value)) {
return convertCents(stripMoney($value, 0), NULL, $toCents);
}
}
What I have done might be overkill, But I think it's fairly solid, other than this 1 detail, that I can see.
can anyone help me with these adjustments?
Do not use floating point arithmetic if you need exact answers. This applies to almost all languages, not just PHP. Read the big warning in the PHP manual.
Instead check out BC Math or the GMP extension. The latter only works with integer numbers so you are probably most interested in BC Math.
I think money_format is the function you were looking for...
<?php
$number = 1234.56;
// let's print the international format for the en_US locale
setlocale(LC_MONETARY, 'en_US');
echo money_format('%i', $number) . "\n";
// USD 1,234.56
// Italian national format with 2 decimals`
setlocale(LC_MONETARY, 'it_IT');
echo money_format('%.2n', $number) . "\n";
// Eu 1.234,56
?>

Convert a string containing a number in scientific notation to a double in PHP

I need help converting a string that contains a number in scientific notation to a double.
Example strings:
"1.8281e-009"
"2.3562e-007"
"0.911348"
I was thinking about just breaking the number into the number on the left and the exponent and than just do the math to generate the number; but is there a better/standard way to do this?
PHP is typeless dynamically typed, meaning it has to parse values to determine their types (recent versions of PHP have type declarations).
In your case, you may simply perform a numerical operation to force PHP to consider the values as numbers (and it understands the scientific notation x.yE-z).
Try for instance
foreach (array("1.8281e-009","2.3562e-007","0.911348") as $a)
{
echo "String $a: Number: " . ($a + 1) . "\n";
}
just adding 1 (you could also subtract zero) will make the strings become numbers, with the right amount of decimals.
Result:
String 1.8281e-009: Number: 1.0000000018281
String 2.3562e-007: Number: 1.00000023562
String 0.911348: Number: 1.911348
You might also cast the result using (float)
$real = (float) "3.141592e-007";
$f = (float) "1.8281e-009";
var_dump($f); // float(1.8281E-9)
Following line of code can help you to display bigint value,
$token= sprintf("%.0f",$scienticNotationNum );
refer with this link.
$float = sprintf('%f', $scientific_notation);
$integer = sprintf('%d', $scientific_notation);
if ($float == $integer)
{
// this is a whole number, so remove all decimals
$output = $integer;
}
else
{
// remove trailing zeroes from the decimal portion
$output = rtrim($float,'0');
$output = rtrim($output,'.');
}
I found a post that used number_format to convert the value from a float scientific notation number to a non-scientific notation number:
Example from the post:
$big_integer = 1202400000;
$formatted_int = number_format($big_integer, 0, '.', '');
echo $formatted_int; //outputs 1202400000 as expected
Use number_format() and rtrim() functions together. Eg
//eg $sciNotation = 2.3649E-8
$number = number_format($sciNotation, 10); //Use $dec_point large enough
echo rtrim($number, '0'); //Remove trailing zeros
I created a function, with more functions (pun not intended)
function decimalNotation($num){
$parts = explode('E', $num);
if(count($parts) != 2){
return $num;
}
$exp = abs(end($parts)) + 3;
$decimal = number_format($num, $exp);
$decimal = rtrim($decimal, '0');
return rtrim($decimal, '.');
}
function decimal_notation($float) {
$parts = explode('E', $float);
if(count($parts) === 2){
$exp = abs(end($parts)) + strlen($parts[0]);
$decimal = number_format($float, $exp);
return rtrim($decimal, '.0');
}
else{
return $float;
}
}
work with 0.000077240388
I tried the +1,-1,/1 solution but that was not sufficient without rounding the number afterwards using round($a,4) or similar

Categories