I decided to go into CImg.h again, and made next().
Here it is:
C:\gmic-cli\CImg>gmic echo {next(3.2)}
[gmic]./ Start G'MIC interpreter (v.3.3.3).
3.2000000000000006
[gmic]./ End G'MIC interpreter.
C:\gmic-cli\CImg>gmic echo {next(nan)}
[gmic]./ Start G'MIC interpreter (v.3.3.3).
nan
[gmic]./ End G'MIC interpreter.
C:\gmic-cli\CImg>gmic echo {next([3.2,5])}
[gmic]./ Start G'MIC interpreter (v.3.3.3).
3.2000000000000006,5.0000000000000009
[gmic]./ End G'MIC interpreter
next(n) generates the next representable number after n. So, it’s n+eps.
For back(n)
C:\gmic-cli\CImg>gmic echo {back(3.2)}
[gmic]./ Start G'MIC interpreter (v.3.3.3).
3.1999999999999997
[gmic]./ End G'MIC interpreter.
C:\gmic-cli\CImg>gmic echo {back(nan)}
[gmic]./ Start G'MIC interpreter (v.3.3.3).
nan
[gmic]./ End G'MIC interpreter.
C:\gmic-cli\CImg>gmic echo {back([3.2,5])}
[gmic]./ Start G'MIC interpreter (v.3.3.3).
3.1999999999999997,4.9999999999999991
[gmic]./ End G'MIC interpreter.
So, would this be useful?
I was thinking about something similar last week, and my impression is that it could be way better to define a new pre-defined variable like eps
that would be the minimal difference between two consecutive double values.
It is better, because :
- Functions
next(x)
and previous(x)
would be simply x+eps
and x - eps
, so that is straightforward.
- You could use
eps
in other functions when necessary (otherwise you would have to do eps = next(x) - x
which is a bit odd to define eps
.
1 Like
Would it make sense to have both of these? I do like the idea of eps being automatically determined at run time and I think that’s more self-documenting.
I’m leaning to just eps if it is possible to do just that.
I’m not a big fan of adding new native functions in the math parser (in this case next()
and previous()
), if they are as simple to define as:
next(x) = (x + eps);
previous(x) = (x - eps);
These functions won’t be used in a lot of situations for sure, and having a native implementation in this case would not even be that faster (it just an addition/subtraction with a constant value).
I tested a use case with modulo using 2.2204460492503131e-16, and it seems better than using next().
C:\gmic-cli\CImg>gmic echo {259%(256+2.2204460492503131e-16)}
[gmic]./ Start G'MIC interpreter (v.3.3.3).
3
[gmic]./ End G'MIC interpreter.
C:\gmic-cli\CImg>gmic echo {259%next(256)}
[gmic]./ Start G'MIC interpreter (v.3.3.3).
2.9999999999999432
[gmic]./ End G'MIC interpreter.
I guess this can be concluded.
Though, I do think there may be some precision issue for very low/high value, like we see here:
C:\gmic-cli\CImg>gmic echo {9007199254740992+2.2204460492503131e-16}
[gmic]./ Start G'MIC interpreter (v.3.3.3).
9007199254740992
[gmic]./ End G'MIC interpreter.
C:\gmic-cli\CImg>gmic echo {next(9007199254740992)}
[gmic]./ Start G'MIC interpreter (v.3.3.3).
9007199254740994
[gmic]./ End G'MIC interpreter.