8 ms·
It's done all the time in JavaScript. Why not in Java?
by chrisseaton 4y ago
It's done all the time in JavaScript. Why not in Java?
- xg15 4y agoI'm surprised this is done in JS. If you're doing any kind of calculation with floats (and use actual non-integer numbers, not just ints stored as floats) then it's generally difficult to get the same exact result every time on every system, due to rounding errors. That's why to my knowledge, any strict equality check on floats is generally frowned upon. (exceptions: you know all the floats are actually non-huge ints; You're comparing with a value the variable was explicitly set to at some time before)
- chrisseaton 4y agoJavaScript conceptually only has floats (ignoring big integers, which isn't what most people use for numbers), so any map of numbers to values is using a float key. You refer to that, but yeah they're all floats. > it's generally difficult to get the same exact result every time on every system, due to rounding errors Floating point arithmetic is 100% entirely deterministic - you don't just get different values randomly.
- cookiengineer 4y agoThis is so wrong ECMAScript does not have maps where keys can be integers and neither can keys be floats. Everything is a pointer to a value, and otherwise reflected with a symbol or string (which in return is a unique symbol). An object doesn't have object[1] because it is actually object[reference("1")] This way boxing and unboxing of arrays is much cheaper, due to the arrays not needing a resizing of their cells once datatypes change. (TypedArrays are optimized in a different manner, but we are speaking about the NaN use case, which implies either an Array or Object) There are dozens of talks about e.g. v8's hidden classes on youtube that show up this very mechanism. No idea where you got that float keys idea from.
- chrisseaton 4y ago> ECMAScript does not have maps where keys can be integers and neither can keys be floats. map = new Map(); map[1] = 3; map[1]; // 3 map[1.2] = 3.4; map[1.2]; // 3.4 typeof(map.keys().next().value); // "number" I'm not an expert in JavaScript. What am I missing?
- xg15 4y agoA nitpick: You're setting object properties on a Map object, which only works "accidentally" but does not make use of the map at all[1]. So in this case, it likely works because the numbers are converted to strings before being used as keys. But in general, using float keys does work - but can fail in unexpected ways due to rounding errors. E.g.: m = new Map(); m.set(0.3, "foo"); // --> Map { 0.3 → "foo" } m.get(0.3); // --> "foo" m.get(0.1 + 0.2); // --> undefined That's because 0.1 + 0.2 == 0.30000000000000004 in IEEE floats, which is != 0.3. [2] So using float keys which are derived from calculations and may contain non-integer numbers is a bad idea, because unless you have very good knowledge about floating point math, you can not easily predict what exact value the result of a calculation will be. [1] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map#setting_object_properties https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe... [2] https://stackoverflow.com/questions/8503157/ieee-754-floating-point-arithmetic-rounding-error-in-c-sharp-and-javascript https://stackoverflow.com/questions/8503157/ieee-754-floatin...
- chrisseaton 4y agoRight - should be using set and get - was written out without running it. But isn't this still a map that has float and integer keys? Why doesn't it count?
- matt_kantor 4y agoObject property names are always strings, even though you can set them via number literals (as the person you replied to said): const object = {} object[1] = 3 console.log(object["1"]) // 3 for (const key in object) { console.log(typeof key) // "string" } This is different from keys of the Map data structure, which are actually able to be any type of value (even silly stuff like other Maps).
- panzi 4y agoIt's done in JavaScript because there is not integer type. (Ok, ok, nowadays there is bigint, but historically.) So you do all int like calculations with number (which is IEEE double), but be sure to only do arithmetic where the result is still an integer. That's why you end up using a double as a numeric key. And I think a double can basically hold a 53 bit integer exactly.
- xg15 4y agoOk, that's different then. Using integers as keys should not be a problem, even if they are stored as floats. Problems start if you use non-integers or IEEE special values as keys.
- idealmedtech 4y agoThis is definitely not my area of expertise, but my understanding was that the mantissa was actually the source of inexactness in floats? I know the power bits (10 bits?) are pretty close to actual twos complement ints, and you could always do things in a C-like union, but I wasn't aware you could directly treat the mantissa like an int
- deleted 4y ago[deleted]
- Ferret7446 4y agoJavascript does a ton of things that are extremely questionable, so it's not a good source to say you should do something. Rather, it's a better argument (though still flawed) to say that because it's done all the time in Javascript, it's evidence that you shouldn't do it.