Every time I see a bizarre mathematical output I am reminded that IEEE 754 is gross as hell. I just use bigints wherever it's possible to transform the algorithm to work with bigints, and I "render to decimal" in views
1.5 is the midpoint between 0 and infinity in Ruby
81–90 of 125 posts
Re: 1.5 is the midpoint between 0 and infinity in Ruby
#82Re: 1.5 is the midpoint between 0 and infinity in Ruby
#83Earlier quoted context omitted.
Kind of but you get significantly better precision than if you just use a normal double float type because doubles only push the issues further out. Especially in games you're likely already breaking the world into cells for streaming chunks into/out of memory anyways.
Isn't this also just pushing the problem out? Once you get far enough out, you wouldn't be able to transition between cells because of the rounding error of the cell boundary being bigger than the cell size. You can't represent infinite precision with finite bits so you must run into an issue eventually.
The visible universe (according to Wikipedia) is 8.8 * 10^26 meters or about 5.4 * 10^61 Plank lengths. That gives us a log2 of 205.1
In other words if my maths is correct if you want to represent the entire visible universe down to the scale of the Planck length you need 206bits of resolution, or 4 64 bit integers with a lot of room to spare.
And if you don't actually aim to simulate subatomic particles you can get down to millimeter resolution with "only" 100bits.
And that's not even taking into account that, our universe being so empty, you can probably fudge super large distances a bit (having a lower resolution at scales where the universe is mostly empty). Nobody is going to notice if Andromeda if a few parsecs closer than it should be.
Re: 1.5 is the midpoint between 0 and infinity in Ruby
#84In surreal numbers [1], the midpoint between 0 and infinity would be the simplest number greater than 0, which is { 0 | } = 1 [1] https://en.wikipedia.org/wiki/Surreal_number
This is also consistent with the old joke that developers count like cavemen: zero, one, many!
Re: 1.5 is the midpoint between 0 and infinity in Ruby
#85Earlier quoted context omitted.
From Python: >>> import numpy as np >>> 1 + np.Inf inf >>> (0 + np.Inf)/2 inf >>> Infinity is not a number it is a concept[1] My math teacher used to say think of infinity like a impossibly large number. An impossibly large number divided by two is still an impossibly large number [1] http://mathforum.org/dr.math/faq/faq.large.numbers.html
While you’re correct, you’re being downvoted probably because you’re taking this seriously. I’m sure most everyone here knows infinity isn’t a number, but a concept, but you never know.
Re: 1.5 is the midpoint between 0 and infinity in Ruby
#86Clearly we'll need to some work in TruffleRuby to be fully compatible. I really hope nobody's code depends on this. Infinity 8.988465674311579e+307 4.4942328371557893e+307 2.2471164185778946e+307 1.1235582092889473e+307 5.6177910464447366e+306 ... 32767.999999999996 16383.999999999998 8191.999999999999 4095.9999999999995 2047.9999999999998 1023.9999999999999 511.99999999999994 255.99999999999997 127.99999999999999 63…
I'm left wondering if this is real behavior, or you're doing a Douglas Adams joke...
Both solutions make sense... the blog post refers to a ieeeinteger representation hack that likely finds answers faster, because it more quickly finds the values that tend to be in realistic numbers. It works by doing a binary search of all possible values representable in floating point (of which there are more for smaller numbers, due to the design tradeoff of IEEE floating point).
The TruffleRuby binary search solution is also "correct" in its own way, in that it's binary searching using the actual floating point values themselves.
Re: 1.5 is the midpoint between 0 and infinity in Ruby
#87Earlier quoted context omitted.
This is also consistent with the old joke that developers count like cavemen: zero, one, many!
Well, if you map the contents of the unit circle (|z| 1. So there really is no need to give unique names to anything beyond 1 as it's already contained in the proverbial nutshell of the unit circle via 1/z.
Re: 1.5 is the midpoint between 0 and infinity in Ruby
#88In surreal numbers [1], the midpoint between 0 and infinity would be the simplest number greater than 0, which is { 0 | } = 1 [1] https://en.wikipedia.org/wiki/Surreal_number
TIL: apart from infinity (number, larger than any real number in absolute value) there are infinitesimal (number, less than any real number in absolute value and not a zero). Edit: also, those infinitesimals were the subject of political and religious controversies in 17th century Europe, including a ban on infinitesimals issued by clerics in Rome in 1632.
Philosophical problems surrounding the perplexing concept of infinity were already hotly debated by the ancient Greeks. Aristotle made an ontological distinction between actual and potential infinities, and argued that actual infinity cannot exist but potential infinity can. This was also the consensus position of later scholars, and became a sticking point in the acceptance of calculus because infinitesimals (and infinite sums of them) were an example of the ontologically questionable actual infinities.
As I mentioned before, standard modern analysis is based on limits, not infinitesimals, and requires no extension of real numbers. Indeed the limit definition of calculus only requires the concept of potential infinities, so philosophers should be able to rest easy! But infinitesimals still occur in our notation which is largely inherited from Leibniz, however. We say that the derivative of y(x) is dy/dx, or the antiderivative of y(x) is ∫ y(x) dx, and while acknowledging that dy and dx are not actual mathematical objects, just syntax, we still do arithmetic on them whenever it's convenient to do so! For example, when we make a change of variables in an integral, we can substitute x = f(t) for some f, and then say dx/dt = f'(t) and "multiply by dt" to get dx = f'(t) dt to figure out what we should put in the place of the "dx" in the integral.
Actual infinitesimal numbers are not dead, either, they're used in a branch of analysis called nonstandard analysis which formalizes them in the logically rigorous manner that is now expected from mathematics.
________
¹ Not that they had a rigorous theory of real numbers, either, that came in the 19th and early 20th century. In fact what we now understand as formal, axiomatized math didn't really exist before the 19th century at all!
Re: 1.5 is the midpoint between 0 and infinity in Ruby
#89I vaguely remember learning similar fact years ago, but it was phrased something like "There are as many floats in [0, 1] range as in [1, infty]". Leaving aside where exactly "midpoint" of floats lies (either in Ruby's implementation or other languages'): what would be implications of this for writing code dealing with floats? Can I shoot myself in the foot somehow with low precision if numbers I'm using are "too clo…
The "number of sig figs" precision will be the same for large values far away from zero, as for values close to zero. E.g. IEEE 64 bit reliably gives you about 15 decimal digits of precision. Any decimal number with 15 digits of precision that is in the range of the IEEE 64 bit double can be converted to that type, and then back to decimal, such that all those digits of precision are recovered.
You can shoot yourself in the foot if you rely on floating-point values being able to exactly represent integers, but the values go beyond the range where that is possible. Beyond a certain range, all consecutive integers are no longer representable; some integers get approximated by nearby integers.
Re: 1.5 is the midpoint between 0 and infinity in Ruby
#90C++ :) #include #include double midpoint(double first, double second) { auto firstAsInt = reinterpret_cast (first); auto secondAsInt = reinterpret_cast (second); auto mid = (secondAsInt + firstAsInt) / 2; return reinterpret_cast (mid); } int main() { std::cout 1.5 = " inf = " ::infinity())
Rant: Technically , that code invokes undefined behavior as you use `reinterpret_cast` to alias variables. The only standards conforming way (prior to `std::bit_cast`[0] in C++20) was to use `memcpy`.[a] `reinterpret_cast` was added for situations where code you have no control over requires a certain type, but you need to force it to take your variable.[b] [a]: As `memcpy` (in addition to reinterpreting bits) copies…