Rendered at 21:11:07 GMT+0000 (Coordinated Universal Time) with Cloudflare Workers.
weinzierl 7 hours ago [-]
The "integer arithmetic paradigm" would mean either checking after (almost) every operation or living with potentially incorrect results.
The first is terribly inefficient, the second is just wrong (even if insanely common).
This is sad because there is no reason at all why integers couldn’t follow what OP calls the "float paradigm". It doesn’t even have to be slow. Most modern processors (if we ignore x86) support some form of sticky arithmetic flags. Unfortunately, programming languages don’t support them, so they aren’t used.
There is also something to be said about
the special treatment division by zero gets.
>I sometimes wish that signed integers were symmetrical. i8 would represent the range of [-127 to 127] with 0xFF representing NaN. Any operation which can not be computed (division by zero, overflows, operation with another NaN, etc.) would result in NaN. For further symmetry we could do the same for signed integers as well.
dnautics 6 hours ago [-]
Pretty sure zig has safe integer operations: integers aren't allowed to overflow with the standard operators, there are overflowing and saturating operators if that's what you want.
kibwen 5 hours ago [-]
> Most modern processors (if we ignore x86) support some form of sticky arithmetic flags. Unfortunately, programming languages don’t support them, so they aren’t used.
I'd say the reason that programming languages don't have built-in support for checking the CPU's sticky status flags is precisely because of a lack of x86 support. Plenty of languages do have support for checking overflow on each individual operation, e.g. Rust's `overflowing_foo` methods, which return a tuple whose second member is a boolean indicating overflow: https://doc.rust-lang.org/std/primitive.i32.html#method.over...
jcranmer 5 hours ago [-]
Sticky flags tend to be really annoying for a compiler to support for various reasons, but principally it makes every operation have a hidden dependency to shared global state that is almost never read. Note that IEEE 754 standardized support for sticky flags 40 years ago, but support for these sticky bits is still poor to nonexistent in most programming languages, and sticky bit stuff for floating-point operations is less problematic than integer operations because FP math is already far more black box in practice.
a_e_k 4 hours ago [-]
For the float stuff, beware of `-ffinite-math-only`. If enabled, `isfinite()` and may compile out as assumed true (with similar assumptions around `isnan()` and `isinf()`).
And `-ffinite-math-only` is enabled by `-ffast-math` which in turn is enabled by `-Ofast`.
toolslive 3 hours ago [-]
Not only that: `-ffast-math` might change the result of flops when the arguments are regular floats too. (It abandons IEEE754 compliance)
dooglius 6 hours ago [-]
FWIW one can configure floating point exceptions at runtime at no overhead, see `man 3 fenv`
jcranmer 5 hours ago [-]
It's no overhead in the same sense that zero-cost exception-handling is zero-cost: turning them on properly (e.g., #pragma STDC FENV_ACCESS ON or equivalent command-line flags) disables a fair amount of optimizations which incurs an overhead in and of itself.
dooglius 2 hours ago [-]
Oh interesting I thought it was more or less a wrapper around MXCSR (or equivalent for other architectures)
dzaima 5 hours ago [-]
Except gcc doesn't actually support it to any sane extent (it ignores and warns on "#pragma STDC FENV_ACCESS ON", which C requires for fenv.h to actually function; and as such gcc makes a bunch invalid optimizations); clang supports it, but only as of somewhat-recently.
The first is terribly inefficient, the second is just wrong (even if insanely common).
This is sad because there is no reason at all why integers couldn’t follow what OP calls the "float paradigm". It doesn’t even have to be slow. Most modern processors (if we ignore x86) support some form of sticky arithmetic flags. Unfortunately, programming languages don’t support them, so they aren’t used.
There is also something to be said about the special treatment division by zero gets.
>I sometimes wish that signed integers were symmetrical. i8 would represent the range of [-127 to 127] with 0xFF representing NaN. Any operation which can not be computed (division by zero, overflows, operation with another NaN, etc.) would result in NaN. For further symmetry we could do the same for signed integers as well.
I'd say the reason that programming languages don't have built-in support for checking the CPU's sticky status flags is precisely because of a lack of x86 support. Plenty of languages do have support for checking overflow on each individual operation, e.g. Rust's `overflowing_foo` methods, which return a tuple whose second member is a boolean indicating overflow: https://doc.rust-lang.org/std/primitive.i32.html#method.over...
And `-ffinite-math-only` is enabled by `-ffast-math` which in turn is enabled by `-Ofast`.
> These eleven functions were defined in C99, and describe the handling of floating-point rounding and exceptions (overflow, zero-divide, etc.).