| |
| ▲ | ack_complete 2 hours ago | parent | next [-] | | This case actually works because for finite numbers of a given sign, the integer bit representations are monotonic with the value due to the placement of the exponent and mantissa fields and the implicit mantissa bit. For instance, 1.0 in IEEE float is 0x3F800000, and the next immediate representable value below it 1.0-e is 0x3F7FFFFF. Signed zero and the sign-magnitude representation is more of an issue, but can be resolved by XORing the sign bit into the mantissa and exponent fields, flipping the negative range. This places -0 adjacent to 0 which is typically enough, and can be fixed up for minimal additional cost (another subtract). | | |
| ▲ | kbolino an hour ago | parent [-] | | I interpreted OP's "bit-cast to integer, strip few least significant bits and then compare for equality" message as suggesting this kind of comparison (Go): func equiv(x, y float32, ignoreBits int) bool {
mask := uint32(0xFFFFFFFF) << ignoreBits
xi, yi := math.Float32bits(x), math.Float32bits(y)
return xi&mask == yi&mask
}
with the sensitivity controlled by ignoreBits, higher values being less sensitive.Supposing y is 1.0 and x is the predecessor of 1.0, the smallest value of ignoreBits for which equiv would return true is 24. But a worst case example is found at the very next power of 2, 2.0 (bitwise 0x40000000), whose predecessor is quite different (bitwise 0x3FFFFFFF). In this case, you'd have to set ignoreBits to 31, and thus equivalence here is no better than checking that the two numbers have the same sign. |
| |
| ▲ | oasisaimlessly 2 hours ago | parent | prev [-] | | I don't think this is true. Modulo the sign bit, the "next float" operator is equivalent to the next bitstring or the integer++. | | |
| ▲ | kbolino 31 minutes ago | parent [-] | | Sure, but that operator can propagate a carry all the way to the most significant bit, so a check for bitwise equality after "strip[ping] few least significant bits" will yield false in some cases. The pathologically worst case for single precision, for example, is illustrated by the value 2.0 (bitwise 0x40000000) and its predecessor, which differ in all bits except the sign. |
|
|