Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.
Sign upDecimal mark dependency #234
Comments
|
Very good catch, wow. |
|
Both strtod() and atod() are in use, each once, and each (annoyingly) takes locale into account. These are not trivial functions to replicate, and locale is typically a process-wide setting. Bringing in streamstring stuff to imbue it with a stream-specific locale also feels heavyweight for this purpose, but perhaps not? Any other ideas? |
|
I ran into the same issue. I am using the glslang static library directly, so calling |
|
@johnkslang For what it's worth, we have a full number parser in the preprocessor. Though it is not the prettiest code; it is straightforward. |
|
strtod() has a variant that takes the locale to use explicitly in both windows (_strtod_l) and linux (strtod_l): Looking around a bit I found a gist with an example to create a strtod that always uses the C locale without affecting the application's locale: https://gist.github.com/tknopp/9271244 |
|
@johnkslang I was writing a standalone number parser, so I looked at the specification to make sure. In looking at the GLSL specification, I think that GLSL's definition of floating-point literals is more narrow than that of a full fledged I'm confident I can write (and exhaustively test) a compact standalone parser which accepts only what's specified, but otherwise behaves like a correct locale-free positive-only decimal-only This could also be a good opportunity to properly handle double constants (seemingly not supported currently due to ambiguity between l/L in integers, and lf/LF in float constants, since the |
|
Basically agreed, and agreed about the accidental inclusion of the HLSL syntax. Otherwise, I think the glslang parser is validating against the spec, it just uses the library functions to create the actual number. |
Fixes #1228. Fixes #234. This uses imbue() to be locale independent. Notes: - 'sstream >> double' is much slower than strtod() * this was measurable in the test suite as a whole, despite being a tiny fraction of what the test suite does - so, this embeds a fast path that bypasses sstream most of the time => the test suite is faster than before - sstream is probably slower, because it does more accurate rounding than strtod() - sstream does not create INFINITY by itself, this was done based on failure inferencing
…st path. Fixes #1228. Fixes #234. This uses imbue() to be locale independent. Notes: - 'sstream >> double' is much slower than strtod() * this was measurable in the test suite as a whole, despite being a tiny fraction of what the test suite does - so, this embeds a fast path that bypasses sstream most of the time => the test suite is faster than before - sstream is probably slower, because it does more accurate rounding than strtod() - sstream does not create INFINITY by itself, this was done based on failure inferencing
|
It turns out this is a quite complex problem. To completely correctly both parse and print double values is ~1000 of lines of code, so I prefer to use library functions. Yet, library functions for these are not completely portable. istringstream is different than strtod, and handles infinities differently, and all functions vary across platforms, and even the ways of controlling them are not standardized, because the C++ standard is not IEEE based. Further, istringstream is very slow. (General side note: to get even close to correct rounding requires slow algorithms, whose performance is dependent on the actual values being translated. These are available in istringstream, and it is worth using them for some values.) I believe, now, I have a combination of
|
|
#1385 has a series of three commits that
These should be locale dependent. If not, it should now be an easy fix. See the pull request for more details. |
Currently the compile time string to binary number parsing depends on the current active locale.
Decimal mark set to "," (e.g. setlocale(LC_ALL, "German_Germany")) produces:
Default Decimal mark "." produces the correct output: