WTF Bites
-
It's 2019. Why is it so hard to print exact value of a double without truncation, without scientific notation and without unnecessary trailing zeros?
Python's
repr
claims to do that (scientific notation used if the exponent is more/less than something) for years, so an implementation certainly exists, but I am not sure whether there is any reasonably small library with it and it certainly never made it into standard library of C or C++, and as far as I can tell neither to the Rust one.The "exact value" of a double-precision float is truncated, to 53 significant binary figures. And they don't play well with decimal, unless you really want to see 0.09999999999999999167332731531132594682276248931884765625, in which case I've been semi-working on something just for you!
Double-precision float has 52 significant binary digits, so it does not have 53 significant decimal digits to print. Any library that gives you that many is printing insignificant digits and should be considered broken.
For every double value there exists a shortest decimal number that will convert back to the original value and that is the one that should be printed. This has 17 (maybe 18 in some cases; I am not sure) significant digits. This is what is requested.
-
And I want all of them because I'm writing a code generator and want to preserve the value exactly when converted to source code and then compiled. Is this really too much to ask? Lossless serialization of one double?
The language of the generated source doesn't support hexfloats or scientific notation? (And is it even capable of accurately parsing decimal doubles that long?)
But, yeah, your rant is on point. Round-tripping doubles to ASCII and back is hairy and filled with all sorts of surprises.
-
@pie_flavor said in WTF Bites:
@Zecc is using Git Bash instead of
PowerShellGitKraken.
-
implementation certainly exists
… and while I am sure I've seen some details about it in the past, I totally can't find them now. The internet is full of newbie questions asking how to format double to two decimal digits and similar RTFM material and the advanced material is buried deep below the pile.
-
GitKraken
Why should I use that? The page is . It has no description of it, no screenshots and just a bunch of videos (and while hosting them on Vimeo gets some internet pointz for not feeding Google, the Privacy Badger has something against them).
-
Python's repr claims to do that (scientific notation used if the exponent is more/less than something) for years, so an implementation certainly exists, but I am not sure whether there is any reasonably small library with it and it certainly never made it into standard library of C or C++, and as far as I can tell neither to the Rust one.
Standard printf?
%e
forces scientific notation,%f
forces adding insignificant digits all the way to the decimal point,%g
toggles between the two.%a
produces hexfloats, my manpage says C99 but not SuSv2.However %g does not give any way to affect which representation you'll be getting, so if you're looking for that you're out of luck. Maybe write your own code based on the value of
(*(uint64_t*)&d >> 52) & 0x7ff
?
-
@PleegWat The requirement is effectively
Print a representation, with minimal possible characters, that when parsed back into a
double
will result in the same value.printf
can't do the rather complex kind of rounding needed for this, and it can't even trim trailing zeroes. None of the formats.And yes, python's
float.__repr__()
does just that.>>> repr((1-1e-16)/10) '0.09999999999999999' >>> repr((1-1e-16)/100) '0.009999999999999998' >>> repr((1-1e-16)/1000) '0.0009999999999999998' >>> repr((1-1e-16)/10000) '9.999999999999999e-05' >>> repr((1-1e-16)/100000) '9.999999999999999e-06' >>> repr(1.0/10000) '0.0001' >>> repr(1.0/100000) '1e-05'
-
while hosting them on Vimeo gets some internet pointz for not feeding Google
I thought the real move is to host their videos on Twitter instead?
-
GitKraken
Why should I use that?
Because git is a turd and avoiding direct interaction with it is a proven sanity preservation strategy.
Plus, although it's Electron based, it manages to be somewhere around 74 times faster than another software turd: SourceTree.The page is . It has no description of it, no screenshots and just a bunch of videos (and while hosting them on Vimeo gets some internet pointz for not feeding Google, the Privacy Badger has something against them).
Yeah, their page is shit.
-
TIL: Did you know
console
in JS accepts format strings when logging?So you can do
console.log('TRWTF is %d', 'you') >> TRWTF is NaN
Except it uses some kind of weird substitution string specs that is different from the C ones. Also it doesn't support recursive substitutions, or substitutions for strings after the first argument.
But there's more!
console.log('TRWTF is %%%%') >> TRWTF is %%%% console.log('TRWTF is %%%%', 'you') >> TRWTF is %% you console.log('Behold:', 'TRWTF is %%%%', 'you') >> Behold: TRWTF is %%%% you
The WTF? This is undocumented.
-
Because git is a turd and avoiding direct interaction with it is a proven sanity preservation strategy.
I admit it is totally inconsistent, but I know it inside out, so I don't mind. And I actually use the complex bits somewhat regularly.
Plus, although it's Electron based, it manages to be somewhere around 74 times faster than another software turd: SourceTree.
SourceTree is mainly turd because it can't do 99% of things I regularly use. Compared to the other GUIs that only can't do about 90% of them. There is absolutely nothing from which I can tell whether GitKraken can do any more than 10% of what I need, but I suppose I can rather safely assume it can't.
-
I admit it is totally inconsistent, but I know it inside out, so I don't mind. And I actually use the complex bits somewhat regularly.
My experience is that if complex parts of git are used in a project then either something's wrong with managing the project, or they are used just for the sake of it.
But that may be my aversion to git speaking.
SourceTree is mainly turd because it can't do 99% of things I regularly use.
It's inconsistent, cluttered and slow screen scraper masquerading as a GUI. Everything wrong with git moved to another layer.
And just like git turd became industry standard for source control, SourceTree turd is industry standard for git GUI. I hate IT so much sometimes.
Compared to the other GUIs that only can't do about 90% of them. There is absolutely nothing from which I can tell whether GitKraken can do any more than 10% of what I need, but I suppose I can rather safely assume it can't.
It can't, it's simple by design.
-
@pie_flavor said in WTF Bites:
@Zecc is using Git Bash instead of PowerShell.
I like Ctrl+R for reverse command search.
No, is devstagduction.
-
Why is it so hard to print exact value of a double
Because math is difficult, even more so than it looks at first glance. Worse, it's much more difficult if you want to also use the shortest representation of the number. (Without that, you can just generate all the significant digits and lop unwanted trailing zeroes off the end.) Doing that requires some truly hairy code, as there are some really evil edge cases.
Float printing is the domain of Great Codethulhu. You have been warned.
-
I admit it is totally inconsistent, but I know it inside out, so I don't mind. And I actually use the complex bits somewhat regularly.
My experience is that if complex parts of git are used in a project then either something's wrong with managing the project, or they are used just for the sake of it.
But that may be my aversion to git speaking.
SourceTree is mainly turd because it can't do 99% of things I regularly use.
It's inconsistent, cluttered and slow screen scraper masquerading as a GUI. Everything wrong with git moved to another layer.
And just like git turd became industry standard for source control, SourceTree turd is industry standard for git GUI. I hate IT so much sometimes.
Compared to the other GUIs that only can't do about 90% of them. There is absolutely nothing from which I can tell whether GitKraken can do any more than 10% of what I need, but I suppose I can rather safely assume it can't.
It can't, it's simple by design.
I tried GitKraken a few years ago, and it was a fountain of errors that eventually CTD'd. The precious few minutes it worked, it was fast but I just found it horrible to use.
-
I tried GitKraken a few years ago, and it was a fountain of errors that eventually CTD'd. The precious few minutes it worked, it was fast but I just found it horrible to use.
It went a long way since then. Meaning I don't encounter any errors in everyday use.
But if you didn't like how you do things in it, then it's not for you.
-
I tried GitKraken a few years ago, and it was a fountain of errors that eventually CTD'd. The precious few minutes it worked, it was fast but I just found it horrible to use.
It went a long way since then. Meaning I don't encounter any errors in everyday use.
But if you didn't like how you do things in it, then it's not for you.Yeah, I'm one of those strange people that are happy on the cli.
That said, git is retarded, and generally the entirely wrong tool for the job everyone uses it for so I'd prefer something else for the most part as far as git is concerned...
-
@pie_flavor said in WTF Bites:
@Zecc is using Git
Bash instead of PowerShell.
-
My experience is that if complex parts of git are used in a project then either something's wrong with managing the project, or they are used just for the sake of it.
Yes, normally you should just use ± git flow and call it a day, but:
- On this project we have a bunch of repositories that all need to be checked out and updated together, so it gets down to good old “how do I do
for x in *
.dvi; do xdvi $x
(/); do (cd $x; git pull --ff-only; git status)
; done
in a gui (better approach would be to userepo
ormr
, which some others are using, but we have a bunch of frugly scripts instead). - On previous project it was mostly standard flow, but then we needed something slightly advanced (I think it involved picking out some changes and applying them to the previous release) and colleague wanted to try it in SourceTree and it couldn't do anything even slightly out of ordinary, I think just merging two arbitrary branches was a problem.
- The projects before that involved git-tfs or git-svn, so a lot of rebase workflow.
- I tend to use rebase workflow myself in any case, because I like to keep the changes clean so that I can check I didn't change anything I didn't intend and to make the review easier. And that means interactive rebase and interactive staging (which
git gui
does well, but the other GUIs not so much or not at all).
- On this project we have a bunch of repositories that all need to be checked out and updated together, so it gets down to good old “how do I do
-
It's 2019. Why is it so hard to print exact value of a double without truncation, without scientific notation and without unnecessary trailing zeros?
The "exact value" of a double-precision float is truncated, to 53 significant binary figures.
And these truncated 53 binary figures is what I want. Because that's the exact value of the double after all the FPU dust settles. I just want to store it in text so the same truncated 53 binary figures get read back later.
@Mason_Wheeler said in WTF Bites:
2/3?
A double. Not a result of division of two doubles.
Division of two doubles... is a double!
Well, technically, yes. But the various @Mason_Wheelers of this forums will point out the impossibility of the task if you don't make this distinction.
(Also : the actual result of every double operation on x87-compatible FPU is a long double (80 bits), and it only gets rounded to regular double on storage.)
And I want all of them because I'm writing a code generator and want to preserve the value exactly when converted to source code and then compiled. Is this really too much to ask? Lossless serialization of one double?
The value that gets printed by any sane conversion is a lossless representation of that value.
That's my point. Java's
String.format("%f")
truncates to 5 digits after decimal point by default. It's insane.
-
And they don't play well with decimal, unless you really want to see 0.09999999999999999167332731531132594682276248931884765625, in which case I've been semi-working on something just for you!
Just feed @Gąska
0x3FB9999999999999
. As everyone knows it's the purest form of a double.I absolutely fucking would reinterpret-cast the value to 64-bit integer if I could. Alas, I'm constrained by the grammar of the language I'm generating code for.
-
And I want all of them because I'm writing a code generator and want to preserve the value exactly when converted to source code and then compiled.
Then why "without scientific notation"?
-
The value that gets printed by any sane conversion is a lossless representation of that value.
The conversions seen in standard libraries of most programming languages are not sane in this sense. The python's is a really notable exception.
-
And I want all of them because I'm writing a code generator and want to preserve the value exactly when converted to source code and then compiled. Is this really too much to ask? Lossless serialization of one double?
The language of the generated source doesn't support hexfloats or scientific notation?
No hexfloats, but yes scientific notation. If I can get Java to print lossless scientific notation before I can get it to print lossless plain decimal, I'll use that.
-
This has 17 (maybe 18 in some cases; I am not sure) significant digits.
17sf is sufficient in all cases to render a
double
exactly, but sometimes massively overkill. You probably don't want 17sf for the representation of0.1
…
-
Today, in error messages from Python:
TypeError: __init__() takes at least 4 arguments (17 given)
(Yes, that is a lot of arguments. That particular class has a lot of twiddly bits. I didn't design it.)
-
Today, in error messages from Python:
TypeError: __init__() takes at least 4 arguments (17 given)
(Yes, that is a lot of arguments. That particular class has a lot of twiddly bits. I didn't design it.)
Surprise me: give me a
__init__() takes at least 0 arguments
error in production code.
-
It's 2019. Why is it so hard to print exact value of a double without truncation, without scientific notation and without unnecessary trailing zeros?
Python's
repr
claims to do that (scientific notation used if the exponent is more/less than something) for years, so an implementation certainly exists, but I am not sure whether there is any reasonably small library with it and it certainly never made it into standard library of C or C++, and as far as I can tell neither to the Rust one.If instead of "exact value" we only require a value that round-trips and doesn't have unnecessary trailing zeros (which is a reasonable requirement but I'm not sure if this is sufficient for @Gąska), then there are such things.
to_chars
/from_chars
is required to round-trip, and if I'm reading STL's statements correctly here, so doesstrtof
https://twitter.com/MikeNicolella/status/992887301536542720
Apparently MSVC uses the Ryu algorithm:
Ryu generates the shortest decimal representation of a floating point number that maintains round-trip safety.
-
@Gąska you could always convert the floats to raw bytes, and then implement your own byte array to float string without loss. It would be painful to code in java though.
-
And they don't play well with decimal, unless you really want to see 0.09999999999999999167332731531132594682276248931884765625, in which case I've been semi-working on something just for you!
Just feed @Gąska
0x3FB9999999999999
. As everyone knows it's the purest form of a double.I absolutely fucking would reinterpret-cast the value to 64-bit integer if I could. Alas, I'm constrained by the grammar of the language I'm generating code for.
-
And they don't play well with decimal, unless you really want to see 0.09999999999999999167332731531132594682276248931884765625, in which case I've been semi-working on something just for you!
Just feed @Gąska
0x3FB9999999999999
. As everyone knows it's the purest form of a double.I absolutely fucking would reinterpret-cast the value to 64-bit integer if I could. Alas, I'm constrained by the grammar of the language I'm generating code for.
Would Double.doubleToRawLongBits work, or is there a problem with the representation it would provide?
-
@Gąska I'm still unclear on what you need / what you can use. Can you use "any" Java stuff but the output needs to be the correct text representation to be parse-able as a double? Why not use a
BigDecimal
and print out that?
-
This post is deleted!
-
And they don't play well with decimal, unless you really want to see 0.09999999999999999167332731531132594682276248931884765625, in which case I've been semi-working on something just for you!
Just feed @Gąska
0x3FB9999999999999
. As everyone knows it's the purest form of a double.I absolutely fucking would reinterpret-cast the value to 64-bit integer if I could. Alas, I'm constrained by the grammar of the language I'm generating code for.
Would Double.doubleToRawLongBits work, or is there a problem with the representation it would provide?
There is a problem in that it's not a valid float literal in the target language.
Why not use a
BigDecimal
and print out that?Because it's a fucking ugly solution and there ought to be a better way to do that than converting to arbitrary precision decimal just so I can print the imprecise number. But I guess that's what I'll end up doing. It beats
DecimalFormat
with six hundred hash signs in pattern.
-
And they don't play well with decimal, unless you really want to see 0.09999999999999999167332731531132594682276248931884765625, in which case I've been semi-working on something just for you!
Just feed @Gąska
0x3FB9999999999999
. As everyone knows it's the purest form of a double.I absolutely fucking would reinterpret-cast the value to 64-bit integer if I could. Alas, I'm constrained by the grammar of the language I'm generating code for.
Would Double.doubleToRawLongBits work, or is there a problem with the representation it would provide?
There is a problem in that it's not a valid float literal in the target language.
Why not use a
BigDecimal
and print out that?Because it's a fucking ugly solution and there ought to be a better way to do that than converting to arbitrary precision decimal just so I can print the imprecise number. But I guess that's what I'll end up doing. It beats
DecimalFormat
with six hundred hash signs in pattern.Which standard is the target language using then?
Should be doable to convert between the formats when you've got the binary representation at least.And yeah, java is rather on the horrible end of the spectrum for trying to do anything low level in.
-
And they don't play well with decimal, unless you really want to see 0.09999999999999999167332731531132594682276248931884765625, in which case I've been semi-working on something just for you!
Just feed @Gąska
0x3FB9999999999999
. As everyone knows it's the purest form of a double.I absolutely fucking would reinterpret-cast the value to 64-bit integer if I could. Alas, I'm constrained by the grammar of the language I'm generating code for.
Would Double.doubleToRawLongBits work, or is there a problem with the representation it would provide?
There is a problem in that it's not a valid float literal in the target language.
Why not use a
BigDecimal
and print out that?Because it's a fucking ugly solution and there ought to be a better way to do that than converting to arbitrary precision decimal just so I can print the imprecise number. But I guess that's what I'll end up doing. It beats
DecimalFormat
with six hundred hash signs in pattern.Which standard is the target language using then?
[0-9]*\.[0-9]+f
. As I said, I'm making a code generator.
-
But I guess that's what I'll end up doing. It beats DecimalFormat with six hundred hash signs in pattern.
If adding a library is an option, the
contains a Java version.
-
And they don't play well with decimal, unless you really want to see 0.09999999999999999167332731531132594682276248931884765625, in which case I've been semi-working on something just for you!
Just feed @Gąska
0x3FB9999999999999
. As everyone knows it's the purest form of a double.I absolutely fucking would reinterpret-cast the value to 64-bit integer if I could. Alas, I'm constrained by the grammar of the language I'm generating code for.
Would Double.doubleToRawLongBits work, or is there a problem with the representation it would provide?
There is a problem in that it's not a valid float literal in the target language.
Why not use a
BigDecimal
and print out that?Because it's a fucking ugly solution and there ought to be a better way to do that than converting to arbitrary precision decimal just so I can print the imprecise number. But I guess that's what I'll end up doing. It beats
DecimalFormat
with six hundred hash signs in pattern.Which standard is the target language using then?
[0-9]*\.[0-9]+f
. As I said, I'm making a code generator.So you really didn't want a reinterpret_cast then?
-
@levicki said in WTF Bites:
Must be because you are using inferior shell.
Indeed, this does not happen in Powershell. Not sure what's going on in Git Bash.
-
@levicki said in WTF Bites:
Must be because you are using inferior shell.
Indeed, this does not happen in Powershell. Not sure what's going on in Git Bash.
Some weird combination of
PATH
, shell expansion and incomplete autocomplete configuration for git, looks like.
-
@levicki said in WTF Bites:
I bet it has something to do with the
/
character in the commit message.I'm sure it does. And it only happens if it is the first very character in the commit message. If there's something else before it, including a space, it doesn't happen. (haven't tried other characters like
'$!()
but I've got better things to do currently)If I use two slashes at the beginning, the commit message will show a single slash and no path expansion occurs. It's like it is escaped somehow.
@boomzilla said in WTF Bites:
Some weird combination of
PATH
, shell expansion and incomplete autocomplete configuration for git, looks like.Likely, but to investigate.
-
Sooo, today the security group at the place I'm currently working raised a flag that some people in my team is sending data to china servers. Upon closer inspection, everyone but me is doing it...
The only apparent thing between all of the computers sending stuff to china that my workstation is lacking is a recent upgrade of the mandated IDE. I'm too to update it whenever the infra group tells me to so I'm about 1.5 years late with mine.So, there is a plugin in that distributed software that's spying and sending stuff to china.
The fun bit is that they are really anal about not installing anything unauthorized. This is an authorized software. And, the security tests are done by the developer that wants that particular bit of software, because the security group aint got time fo dat.
So, in reality, they could just let everyone install everything they want, because that's what they are doing anyway, with added bureaucracy .And, as a bonus, when it was discovered that I hadn't upgraded, they gave me some shit about that. Because it might be a security issue if I don't upgrade.
-
I'm signed in to my work email via Outlook Web Access. For whatever reason, it makes me log back in every hour or so (). They use a single-sign on provider that automatically expires logins, but Outlook also automatically logs out.
Outlook tries to log me out, but discovers my single sign on token is expired, so I get redirected to a login page to re-enter my password and 2FA auth... After I finish that process, it resumes where it left off, and finishes logging me out and I'm prompted to sign in again.
-
I'm sure it does. And it only happens if it is the first very character in the commit message. If there's something else before it, including a space, it doesn't happen. (haven't tried other characters like '$!() but I've got better things to do currently)
If I use two slashes at the beginning, the commit message will show a single slash and no path expansion occurs. It's like it is escaped somehow.Git-for-Windows, the bash that accompanies it and most of the tools are derived from MSys2. This is a fork of Cygwin, but adds back the logic that original MSys had to provide ‘compatibility’ between msys and native tools, by converting the paths.
The
exec
function in the msys standard library—this has nothing at all to do with the shell—converts everything that looks like a unix-style path to a windows-style path, and the prologue invokingmain
in the same library does the opposite translation. Starting with / it looks like an absolute path, so it gets translated to windows-style. But the root of the msys filesystem is it's install directory (drives are mapped on /<letter>), so/something
is translated toC:\Program Files\Git\something
. And then the prologue in_start
converts the backslashes back to forward slashes, ending up withC:/Program Files/Git/something
.//
is escape for use with DOS commands that use/
as option prefix, so//
gets translated to/
and nothing else happens—unless the argument happens to look like UNC path, in which case it gets left like that (but my experience was that Git can't be made to understand UNC paths, only mapped drives).Since it has nothing to do with shell, other shell special characters are not affected. However, the
$
has some special meaning for paths under some conditions I don't really understand, and I was unable to get$
properly through togit-tfs
from the msys2 shell (any of them; I also had full msys2 installation) and had to usecmd
for somegit-tfs
setup command.Last but not least there is an environment variable that you can set to disable the translation for arguments matching a pattern (I don't remember the name; it is in the documentation somewhere). I think I ended up summarily disabling at some point (setting the variable to
*
) to no longer have to worry about the$
cases—the path translation has to be done manually in half of the cases anyway.
-
Sooo, today the security group at the place I'm currently working raised a flag that some people in my team is sending data to china servers. Upon closer inspection, everyone but me is doing it...
The only apparent thing between all of the computers sending stuff to china that my workstation is lacking is a recent upgrade of the mandated IDE. I'm too to update it whenever the infra group tells me to so I'm about 1.5 years late with mine.So, there is a plugin in that distributed software that's spying and sending stuff to china.
I'm sure there's some left-pad function somewhere that has already sent
youreverybody's data to China a long time ago.
-
@Gąska I'm still unclear on what you need / what you can use. Can you use "any" Java stuff but the output needs to be the correct text representation to be parse-able as a double? Why not use a
BigDecimal
and print out that?Turns out
BigDecimal.toPlainString()
doesn't print decimal point at all if the fractional part is zero. I am very lucky that I'm not generating a language like C and I can actually just slap "f" after an integer and it works.
-
@Carnage which IDE is it, if I may ask?
-
@Carnage which IDE is it, if I may ask?
IntelliJ, with like 50 annoying fucking plugins that pops up nag screens and notifications about all kinds of shit my team isn't using.
-
@Carnage fuck. We use IntelliJ at work too. Do you know which plugin is the bad actor?
-
@Carnage fuck. We use IntelliJ at work too. Do you know which plugin is the bad actor?
No idea, I am of no inclination to upgrade to deal with the mass of plugins I have to remove or otherwise get to stfu. Even less now that I know there's spyware in one of them as well. And it seems everyone else just and keeps working. To boot, the security group wont tell us anything about target hosts or anything to help with looking into it.
Edit; Oh yeah. They are also blocking any kind of virtual machine, so I can't test it in a sandbox either.
I wonder how the fuck they expect people to do a proper security audit of the software they want accepted to begin with under these lockdowns...