NotionCommotion Posted April 19, 2018 Share Posted April 19, 2018 1.0000000298023224 is returned from a SQL query, and obviously is 1, and I wish to round it to 1, and as such, round($number,4) might be a good choice. That same query, however, could just as well returned 0.0000000298023224 which for my application should not be interpreted as 0, and I wish to round it to 0.00000002980, and as such, round($number,12) might be a good choice. Is there a function to do so, or will I need to do something like the following? PS. Noticed that PHP will automatically round 99999999999.0000000298023224 to 99999999999. PSS. To do so using MySQL (actually MariaDB), will a routine be required? function myRound($number) { if(!$number) return 0; $abs=abs($number); if($abs>=1) return round($number,4); $inv=1/$number; $inv=(int)$inv; $precision=strlen($inv); return round($number, $precision+4); } echo(myRound(.0000000298023224)."\n"); //2.9802E-8 echo(myRound(1.0000000298023224)."\n"); //1 echo(myRound(99999999999.0000000298023224)."\n"); //99999999999 echo(myRound(0)."\n"); //0 echo(myRound(-.0000000298023224)."\n"); //-2.98023E-8 echo(myRound(-1.0000000298023224)."\n"); //-1 echo(myRound(-99999999999.0000000298023224)."\n"); //-99999999999 Quote Link to comment Share on other sites More sharing options...
Phi11W Posted April 19, 2018 Share Posted April 19, 2018 1.0000000298023224 is returned from a SQL query, and obviously is 1, and I wish to round it to 1, and as such, round($number,4) might be a good choice. That same query, however, could just as well returned 0.0000000298023224 which for my application should not be interpreted as 0 I fail to see the difference between the two cases. If the deciding factor is whether the magnitude of the value is greater than [or equal to] one, then CASE operator in the SQL should suffice. select case when abs( value ) >= 1 then round( value, 4 ) else value end value from ... Regards, Phill W. Quote Link to comment Share on other sites More sharing options...
requinix Posted April 19, 2018 Share Posted April 19, 2018 1.0000000298023224 is returned from a SQL query, and obviously is 1,It's obvious? Sure I think it's supposed to be 1, but it could be 1.00000003 or 1.0000000298 or even literally 1.0000000298023224. If you have specific knowledge about why it's supposed to be 1 then you should be able to express that knowledge using code. Quote Link to comment Share on other sites More sharing options...
NotionCommotion Posted April 20, 2018 Author Share Posted April 20, 2018 Thanks Phi11W and requinix, The values in question represent gain scalars. For one application, maybe it is 0.0000000000000123123 so I might want to use round($number,20), but for another application it might be several million so rounding as I did for the small gain is not applicable. I should have used the term significant figures or significant figures in my initial post. I've since googled using this term and found more written on the subject. Quote Link to comment Share on other sites More sharing options...
kicken Posted April 20, 2018 Share Posted April 20, 2018 What doesn't make any sense to me is why 1.0000000298023224 is close enough to one to be considered 1, but 0.0000000298023224 isn't close enough to zero to be considered 0. Pick a precision that is acceptable and use that in all cases. Quote Link to comment Share on other sites More sharing options...
NotionCommotion Posted April 20, 2018 Author Share Posted April 20, 2018 What doesn't make any sense to me is why 1.0000000298023224 is close enough to one to be considered 1, but 0.0000000298023224 isn't close enough to zero to be considered 0. Pick a precision that is acceptable and use that in all cases. What would you rather have, a trillion dollars multiplied by0.0000000298023224 or a hundred dollars multiplied by1.0000000298023224? Quote Link to comment Share on other sites More sharing options...
kicken Posted April 20, 2018 Share Posted April 20, 2018 What would you rather have, a trillion dollars multiplied by0.0000000298023224 or a hundred dollars multiplied by1.0000000298023224? How is that even a relevant question? It's comparing apples to oranges. A more relevant question may be Would you rather have a trillion dollars multiplied by 0.0000000298023224 or multiplied by 0. The answer would be to use the fraction, not zero. The same would be true for 1.0000000298023224 vs 1. 1 Quote Link to comment Share on other sites More sharing options...
NotionCommotion Posted April 20, 2018 Author Share Posted April 20, 2018 Not relevant at all how written, and should have added "where the constant is rounded to 4 decimal points". Just saying that the percent error based on change in precision depends on the magnitude of the value. For my specific case, the user provides some constants which are applied to several variables which are combined. v1 = 4*v2 + 100*v3 + 49*v4. Some of the variables are values in a database but others are similar equations. v2 = 50 *v3 + 10*v5 This recursiveness can theoretically go on forever, but will likely only go 4 or 5 levels. The constants are also stored in another table in the db. My application executes a recursive cte to find all the constants necessary to be applied to the real values: v1 = 300.0000000001234*v3 + 49.00000000012312*v4 + 10.0000000004314*v5 I don't wish to display this, but ideally v1 = 300*v3 + 49*v4 + 10*v5, or worst case v1 = 300.0000*v3 + 49.0000*v4 + 10.0000*v5. But I can't arbitrarily round to four digits because instead of a constant of 49, it might be 0.000049. If I did, and v3 was a hundred dollars, v4 was a trillion dollars, and v5 was twenty dollars, the error would be 49 million dollars! Actually, the values are environmental data, but you get the idea. So, instead of using a given precision, I need to specify a required percentage accuracy and round accordingly. Quote Link to comment Share on other sites More sharing options...
requinix Posted April 21, 2018 Share Posted April 21, 2018 I don't think you want literally to round based on percentages. That will backfire for large/small enough numbers. You can round to a number of significant digits with log10 and round. Throw in sprintf to avoid scientific notation and function round_sf($n, $sf) { $dp = $sf - ceil(log10($n)); return sprintf("%." . max($dp, 0) . "f", round($n, $dp)); }Please don't ask about how you should determine how many significant digits to use. Quote Link to comment Share on other sites More sharing options...
NotionCommotion Posted April 21, 2018 Author Share Posted April 21, 2018 Please don't ask about how you should determine how many significant digits to use. No, I got that handled. Thanks Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.