|
dee679 Newbie
Joined: 16 Oct 2004 Posts: 3
|
Posted: Wed Nov 17, 2004 10:08 am
Division |
Trying to create a simple division alias. Now, it works in most cases (converts integers to floats if they're not already, to prevent that from being messed up).
Code: |
#alias {div} {
#IF (%isfloat(%1)) {@div1 = %1} {@div1 = %float(%1)}
#IF (%isfloat(%2)) {@div2 = %2} {@div2 = %float(%2)}
#IF (%2 == %2) {
#MATH value @div1/@div2
#ECHO @div1 / @div2 = @value
} {
@lvalue = @value
#MATH value @value/@div1
#ECHO @lvalue / @div1 = @value
}
}
|
Apparently, however, some numbers (10000 say) can't be converted to floats, so they still give errors when you divide them. This being the problem that I'm looking to solve. Case in point:
#MATH rat 100.0/10000.0;#echo @rat
Gives an answer of "0.00999999977648258" instead of "0.01"
Any ideas? The only reason I'm not fond of rounding strategies, is that none that I've seen so far have the ability to respect significant figures when deciding how to round.[/code] |
|
|
|
Vorax Apprentice
Joined: 29 Jun 2001 Posts: 198 Location: USA
|
Posted: Wed Nov 17, 2004 12:27 pm |
Instead of having all those #IF's and %isfloat's, you can simplify it like this:
#ALIAS div {#ECHO %1 / %2 = %eval(%float(%1)/%float(%2))}
However, this still gives results: 100.0 / 10000.0 = 0.00999999977648258. |
|
|
|
nexela Wizard
Joined: 15 Jan 2002 Posts: 1644 Location: USA
|
Posted: Wed Nov 17, 2004 1:34 pm |
IS this what your looking for? I'm not gonna play math wiz here cause floating point numbers and division tend to be the last thing on my mind this early in the day. But this will correctly round it up to 2 decimal places as far as I can tell
#ALIAS Div {#ECHO %1 / %2 = %format( "&.2f", %eval( %float( %1)/%float( %2)))} |
|
|
|
dee679 Newbie
Joined: 16 Oct 2004 Posts: 3
|
Posted: Wed Nov 17, 2004 7:16 pm |
Nyeh. No. Because with that rat example, that would return an answer of 0.00. Which is also inaccurate.
|
|
|
|
Vijilante SubAdmin
Joined: 18 Nov 2001 Posts: 5182
|
Posted: Thu Nov 18, 2004 12:29 am |
Put simply flotaing point numbers are flaky. All variables in zScript are stored as strings. When doing math the string is examined to see if it should be handled by the floating point operators. If it does then it is converted and sent out to a library Zugg did not write and processed. The result is converted back to a string. You can try out the %norm function, and if you are not satisfied with it you can then go and do what programmers have done for years. Multiply first to provide enough decimal places, then divide, then insert your decimal point in the right place. While this still provides "rounding" errors it is really a question of how many digits are significant. You can also use this tactic to adjust the results of the %round function. If 3 are significant and your script provides 4 then the user can make the judgement on 3 digits. Overall in statistical analysis 2 digits is plenty and even with rounding errors the results are not affected. So I guess this becomes a question of how precise you really need to be. If you need to be more precise then zScript can handle you should write a program in an actual programming language to handle it. If you just want to be more precise then you should think whether that want is worth the effort.
I have setup scripts before that worked to 15 significant digits during internal calculations, but only displayed one to the user. The script then adjusted down the number of digits as more data was gained because it did not have any major affect on the result that the user would see. The accuracy came more from having more data then from more digits in the calculation. It is like flipping a coin once and because heads came up deciding that all flips of a coin will be heads versus flipping it 50 time and determining that 60% will be heads and 40% tails. Perhaps if we knew what you were using it for we could customize some math to provide the most accuracy in all situations. |
|
_________________ The only good questions are the ones we have never answered before.
Search the Forums |
|
|
|
|
|