-
-
Notifications
You must be signed in to change notification settings - Fork 21.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Logarithm Precision #30194
Comments
Is this really a precision issue? If the result is very close to but below 3 (think 2.9999999 or something), then printing it out might round it to 3, but flooring it will give you 2. I think what you would want to do in this situation is round the result, not floor it. How are you determining what the result of |
I think it is a precision issue but it might be a floating point one in general not specific to godot? I had to add a line checking for (almost?)-equality otherwise the rounding down would be one short.
|
Why not just do
This isn't a Godot-specific issue, general-purpose logarithms are just implemented approximately. In Python, if I do If you really need an exact way to calculate EDIT: You could implement an exact EDIT2: Had an error in my code |
because that would overestimate the number of significant digits needed to represent id in base (when the log is greater than 2.5 but less than 3, and round eagerly bumps it up to 3).
while you only need it only becomes a problem (with floating point) when id is close to (if not exactly) 1000, because then the calculated log might still be 2.99999997 or something but the actual log is 3 (or higher). You are probably right in that it is not a godot-specific issue though. |
I don't think your workaround is perfect though, because what if the real log is actually something like Anyway, if you need exact |
The bottom line is what you're doing would require |
if the real log is 2.9999 which floors to 2, then |
Doesn't that also assume that exponentiation is computed exactly? |
That's not a Godot issue indeed, it's just a normal floating point precision error. There are various strategies to work it around well documented on the Internet, but one which could work here is something like that:
|
That doesn't work for the same reason as rounding, that you might actually have a logarithm that's integer value minus epsilon. |
is exponentiation with integers (or integers converted to floats) ever not exact? edit: well, assuming you are not going ridiculously high with your values that is. |
It does work better than rounding, as rounding gives you wrong values for everything from 1.50001 to 1.99998, while flooring after adding an epsilon only means that your precision is as high as the epsilon. I took an epsilon of 0.00001 as a conservative value, but you can likely make it a tad smaller and still have decent results. But you can't have more precision than what the epsilon accounts for with floating point, that's why it's an epsilon. You will have errors with floating point, that's in their definition. If you want perfect math up to the n-th place, you need to use another approach without ever touching floating point numbers. |
In my testing with small numbers, no, but there's no guarantee that it will be exact so I wouldn't code based on that assumption. An integer can be too big to be represented exactly in floating point, but it seems like your code's use case wouldn't encounter big numbers like that(?)
That's true, but there is an exact solution for the case of integer operands and flooring the result (the one I posted earlier) that's not too bad asymptotically (but maybe would have painful overhead from implementation in GDScript). |
Godot version: 3.1
OS/device including version: Windows 10
Issue description:
Precision issues with flooring a value produced by a logarithmic operation:
floor(log(1000)/log(10)) yields 2 as a result
int(log(1000)/log(10)) yields 2 as a result
In both cases, the expected result was 3 because log(1000)/log(10) yields 3 as a result
Steps to reproduce:
print(floor(log(1000)/log(10)))
print(int(log(1000)/log(10)))
Minimal reproduction project:
Logarithm Precision Issue.zip
The text was updated successfully, but these errors were encountered: