Jump to content

Round number based on the magnitude of that number


NotionCommotion

Recommended Posts

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
 
Link to comment
Share on other sites

 

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.
Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.