-3

I have let's say 0.00001004 or 0.00001

I am trying to choose and how decimal places to prune off and turn both of those so it returns 0.00001 both times.

I do not want it to round the number in anyway.

I've tried this but it is not giving me the desired results.

function decimalFix($number, $decimals) { 
   return floatval(bcdiv($number, 1, $decimals)); 
}

echo decimalFix(0.00001, 5); // returns "0"

Does anyone know what I can do? I can't have any rounding involved and I need it to return it as a float and not a string.

bryan
  • 8,879
  • 18
  • 83
  • 166
  • 2
    Are you looking for `number_format` perhaps? – Tim Lewis Dec 20 '17 at 18:57
  • No because I don't want it to round @TimLewis – bryan Dec 20 '17 at 18:57
  • [PHP How do I round down to two decimal places?](https://stackoverflow.com/questions/12277945/php-how-do-i-round-down-to-two-decimal-places) – FirstOne Dec 20 '17 at 18:58
  • Possible duplicate of [PHP dropping decimals without rounding up](https://stackoverflow.com/questions/9079158/php-dropping-decimals-without-rounding-up) – Caitlyn Dec 20 '17 at 18:59
  • `number_format(0.000019, 5)` returns `0.00002` and not `0.00001` @TimLewis – bryan Dec 20 '17 at 18:59
  • @meowgoesthedog I don't want it to round up if it's `>=5` – bryan Dec 20 '17 at 19:01
  • Huh; you are correct. I could have sworn it didn't do that, but testing does prove otherwise. So maybe you're not looking for `number_format` exclusively. – Tim Lewis Dec 20 '17 at 19:02
  • @meowgoesthedog Yeah, they did actually: "I can't have any rounding involved and I need it to return it as a float and not a string." – Tim Lewis Dec 20 '17 at 19:05
  • @meowgoesthedog you're wrong. `round(0.000018, 5, PHP_ROUND_HALF_DOWN)` returns `0.00002` I need it to give me `0.00001` – bryan Dec 20 '17 at 19:11
  • @bryan my bad, I misread the specification for this argument (it only rounds down past the half-way point). There is a comment at the foot of [that page](http://php.net/manual/en/function.round.php#allnotes) which gives an implementation for `round_down`. – meowgoesthedog Dec 20 '17 at 19:17
  • Possible duplicate of [Truncate float numbers with PHP](https://stackoverflow.com/questions/4668628/truncate-float-numbers-with-php) – rickdenhaan Dec 20 '17 at 19:40
  • 1
    Why do you even want to do this in the first place? – Sammitch Dec 20 '17 at 20:06
  • @Sammitch I am restricted in how many decimal places but still need to keep track of the excess runoff – bryan Dec 20 '17 at 20:13
  • Ok, but *why*? You question sounds more and more like something that need to be handled *entirely differently*, but to know for sure we need to know what exactly you're doing. – Sammitch Dec 20 '17 at 20:30
  • This is what I NEED to do. `$number = $original_number - $truncated_number` so that I can get the excess decimal. So example `$number = 0.00001983 - 0.00001`. But I need to use the `$truncated_number` in other places so just being able to do that equation doesn't entirely help me. @Sammitch – bryan Dec 20 '17 at 20:44

2 Answers2

1

I don't know why you're so committed to losing precision, but here's some math to make that particular mistake in the way you wish to make it.

$derp = 0.000016;

function derp_round($derp, $len) {
    $mul = pow(10, $len);
    return floor($derp * $mul)/$mul;
}

var_dump(
    $derp,
    number_format($derp, 5),
    sprintf("%.5f", $derp),
    sprintf("%.5f", round($derp, 5, PHP_ROUND_HALF_DOWN)),
    sprintf("%.5f", derp_round($derp, 5))
);

Output:

float(1.6E-5)
string(7) "0.00002"
string(7) "0.00002"
string(7) "0.00002"
string(7) "0.00001"
Sammitch
  • 30,782
  • 7
  • 50
  • 77
  • 1
    Note that this has the exact same float precision problem as the first function in my answer: flooring 0.29 to 2 decimals returns 0.28: https://3v4l.org/8eD8Y – rickdenhaan Dec 20 '17 at 19:27
  • @rickdenhaan ugh – bryan Dec 20 '17 at 19:34
  • Nice catch, but see where I said "losing precision"? Welcome to floating point! This is a bad idea and I don't think that there's a good reason to even *want* to do this. – Sammitch Dec 20 '17 at 20:11
  • Don't be mad because you can't comprehend a good reason. The fact that NO ONE on stack overflow has given a foolproof solution shows that this is infact a good question so thanks for the downvote @Sammitch – bryan Jan 06 '18 at 18:06
0

There's a function that does exactly this in the first comment on the PHP documentation for floor(). I'll copy it here in case it disappears from there, but credits go to seppili_:

function floordec($zahl,$decimals=2){    
     return floor($zahl*pow(10,$decimals))/pow(10,$decimals);
}

Use it like:

$number = 0.00001004;

$rounded = floordec($number, 5);
var_dump($rounded); // float(0.00001)

Edit: There's a comment further down on that page by Leon Grdic that warns about float precision and offers this updated version:

function floordec($value,$decimals=2){    
    return floor($value*pow(10,$decimals)+0.5)/pow(10,$decimals);
}

Usage is the same.

rickdenhaan
  • 10,857
  • 28
  • 37
  • The "fix" doesn't work. It rounds the float's up. But the original one does. But I'm afraid now I'll run into problems. – bryan Dec 20 '17 at 19:12
  • Turns out this question had been asked before, [this answer](https://stackoverflow.com/a/28328463/1941241) from that question seems to work for all the cases I've found where the other answers here have issues with float precision. – rickdenhaan Dec 20 '17 at 19:41