• Bill P. Godfrey (unregistered)

    Zeroth. (May be a rounding error.)

  • that other guy (unregistered) in reply to Bill P. Godfrey

    Don't you mean zreoth?

  • TheOtherMerlin (unregistered)


    Consistency can also be rounded apparantly.

    I still do not know how to generalize this solution to ASCII strings in a way that is only half broken.

  • bvs23bkv33 (unregistered)

    first but floated away

  • El Dorko (unregistered)

    "The vendor, to their credit, tracked down the bug and had a patched version to Michael within two days." - there's the real WTF. That just doesn't happen.

  • Little Bobby Tables (unregistered)


    This reminds me of when we found we suddenly had to rewrite our routines to queue up a load of report files for printing. This was in the days of the old DEC VAX kit. We had just bought a super new printer, which required that something low-level changed. This new something then decided that it was going to print all the report files in order of size. So rather than create our reports as front page, body, back page (from 3 files per report -- the front and back pages were either end of the report as it went into an envelope for mailing -- it was all quite complicated and intricate), it printed out all the front and back pages (in whatever order), then all the reports. This necessitated the time-consuming and tedious task of manually collating the reports.

    So we rapidly hacked together a tool to assemble each of the 3 report files into one file before sending it to printing. Simples. Of course we had to make the report file unique, and also sortable by time, so we put an extension on the filename of the format ddMMhhmmss-nnn (for some reason, not my decision) where nnn was milliseconds. That proved to be adequate. We were of course limited by the number of characters in the filename, which was a feature which initially gave us a headache. But it worked.

    That is, up until the 22nd of the month, when everything fell over in a heap. On investigating, we found that some doofus had coded the extension as a pair of integers. And on the 22nd of the month, the first of those integers went over 2^32-1. Herp derp.

  • Martijn Lievaart (unregistered)

    @Little Bobby Tables, I remember that date. Because all of our customers of a certain application couldn't log in, due to the same bug. Fun times, the application ran locally and this was way before the Internet, or even modems being a common thing, we had to ride out to all those customers to deploy the fixed software.

  • WhatEver (unregistered)

    The "Japanese" notation??? Really?!?!? Like ISO8601 doesn't even exist.

  • (nodebb)

    Floating point for dates often derives from using fractional dates to represent time......

  • Darkenon (unregistered) in reply to El Dorko

    This does happen, and as the Vendor, I've done even better. It was a slow afternoon as I had finished everything assigned to me for the day, and the customer service team called up my boss and told him that our largest customer had found a bug in our code that was stopping them from completing parts of their business process (Can't really get into specifics as it is pretty niche and will narrow down the business involved to a small handful).

    The bug was pretty simple and so I found it quickly, ran all of the tests and has the new release shipped to the customer within the space of 3 hours.

  • Foo AKA Fooo (unregistered) in reply to WhatEver

    Of course, ISO8601 doesn't exist to Muricans, just like SI. Though I'm still not sure if by "Japanese notation" they mean the YYYYDDMM format (as supported by Wikipedia; that would indeed be just ISO8601), or storing that as an integer (which doesn't seem to be a typical Japanese thing, and doesn't even make much sense outside of certain software).

    "That's a super common approach to encoding a date as a 32-bit integer." [citation required] I've seen Unix time and various other number-of-seconds (or milli/micro/nano seconds, or days) based formats ,I've seen DOS time with its strange bit fields and a few other formats, but never this. So, super common in SAP universe, or what?

    Fractional dates, as TheCPUWizard suggeset, only make sense when the integer part is the number of days (or perhaps seconds, or years, ...), so you can do actual arithmetic on them. Otherwise, storing a digit sequence as an integer like here is just as stupid as storing ZIP codes as integers.

    "This hadn't been happening in early testing because they safely avoided date/numbers "large" enough. " So they hadn't tested with dates after 1678-01-01 (the first to round wrong). Now, that's what I call a legacy system!

  • Little Bobby Tables (unregistered) in reply to Martijn Lievaart

    Martijn Lievaart -- you wouldn't happen to have been working at Alexandra House at the time, by any chance? If so, then I remember you well.

  • my name is missing (unregistered)

    There are two difficult things in programming, naming things and date times. Some days it's even harder, but the day keeps changing for some reason.

  • King (unregistered)

    Why did they not use this useful feature when they decided on a release date? Floating deadlines...

  • Zach (unregistered)

    I'm confused, maybe someone can help me. How would converting the date to a float all of a sudden change the date (or the int)?

  • Altaree (unregistered)

    "Never attribute to malice what could be explained by incompetence- unless it's a major enterprise product vendor, in which case they really just want to sell you consulting." -- A previous DailyWTF

  • Paul (unregistered) in reply to Little Bobby Tables

    Not much to do with data types and conversion errors, but I inherited a program that also needed unique names for temp files, and the original coder decided on hhmmss (it deleted the file the batch was done), way back when the process took a second or 4 to complete. Then, the customer upgraded their computer, and all of a sudden it only took half a second. This of course wreaked havoc on the output. The 'solution' of the original coder? Put a MsgBox() in the loop, forcing the user to press a button. Putting a book on the keyboard of course wasn't an option, and if the customer was too soon clicking the button it would also fail...

    I wasn't length-constrained so I changed it (who needs modern stuff like Path.GetTempPath...) to hhmmssnnn and I removed the MsgBox(). As they were looping over close to a 1000 items the customer was lyrical. I still don't know what the original coder thought...

  • Guest (unregistered) in reply to Zach

    Floats are effectively power-of-two scientific notation. So, 20181022 becomes 2.0181022 x 10^8 (but in base 2). If the number doesn't divide evenly by two in the conversion from base 10 to base 2, then you lose accuracy. When converting back to an integer, the system has to round, and given the loss of accuracy, it could round back in the wrong direction.

  • profke (unregistered) in reply to El Dorko

    you mean: the vendor provided the already built - but never distributed- fix, billing the customer enterprisy tariffes for 48h non-stop,double-billable hours, the same amount they bill every other customer who happens to encounter this bug, instead of asking the highly paid consultants to do the migration themselves?

  • Foo AKA Fooo (unregistered) in reply to Paul

    Must be from a time where the sleep function wasn't invented yet. Kids today have it so easy, everything is automated. Back then, nothing was automated, even waiting was a task that a computer couldn't do by itself!

    But don't worry, we have the perfect solution (available with a $$$ consulting contract): https://www.youtube.com/watch?v=R_rF4kcqLkI&t%3A=&t=2m55s

  • 3090 (unregistered)

    Before SQL server had the Date() datatype a commons way to strip the time off of datetime() values was to cast the datetime() value to a float, get the floor() of the float and then cast back to datetime()

  • Hyman Rosen (unregistered) in reply to Zach

    A 32-bit binary float can represent every 6-significant-digit decimal value uniquely. (Actually, for the range of dates in the YYYYMMDD notation, it can represent every 7-significant-digit decimal uniquely.) It cannot represent every 8-significant-digit decimal uniquely, so there will exist pairs YYYYMMDA and YYYYMMDB that both convert to the same float, after which it is obviously impossible to recover the original decimal value.

    The 32-bit float 0x4B99F840 is exactly 20181120. The next value, 0x4B99F841, is exactly 20181122. That leaves 20181121 out of luck - it's exactly halfway between two representable numbers, and it will convert to one of them.

  • nate (unregistered)

    I find it interesting that they never hit the bug during testing -- either all their test data sets were from more than 300 years ago (in which case they'd fully earned the WTF themselves), or they were all even day-of-month numbers. A single first-of-month date would have been sufficient to catch the bug (unless there was some kind of data validation code in the converter that silently converted "January 0th" to "January 1st" instead of throwing an error, which would be another WTF).

  • Ross Presser (google)

    See https://en.wikipedia.org/wiki/Single-precision_floating-point_format#Precision_limits_on_integer_values

    Basically, there aren't enough bits in a two-byte float to store 20181121 exactly; it gets rounded to the nearest even number. This is true for all dates since 1677-12-31.

    In fact, if the date had ended in 01, you'd have gotten an invalid date from the rounding. (int)(float)Int32.Parse("20180101") == 20180100

    Addendum 2018-10-08 11:13: EDIT: I meant a four-byte float

  • Object delete. (unregistered) in reply to Little Bobby Tables

    Immeditate fix to the printing problem: {INIT/QUEUE, START/QUEUE, SET QUEUE}/SCHEDULE=NOSIZE Just RTFM. Different printer drivers had different defaults, this usually happened when changing from a text mode printer to a PostScript printer. Ok, we needed a few days to find that, too, at the time.

  • Lorens (unregistered) in reply to El Dorko

    Well I have experienced first-line 24/7 support able to track a down a subtle race condition in their (open-sourced) code in less than two hours after I opened a critical ticket ("fails sometimes" is a criticality level just below "nothing works at all"). First line support even devised a patch that could be understood by anyone having completed Programming with Threads 101.

    The patch was applied to source trees of all newer versions during the next few days.

    I was really impressed.

    The patch was never applied to our version tree because our version's End of Support was just one month in the future and they didn't care to roll a new release. The reason we hadn't upgraded yet was because their newer versions removed a feature we (and a lot of other clients) were depending on.

    They lost a lot of clients.

    Moral: your tech support might be good, but your Product Management also has to be good.

  • (nodebb)

    Floating point is dangerous when you need to be precise. I did some work with money (in the early 70's) with floating point, and rapidly found out that things over $1000 didn't work out well. I ended up doing double precision, but that was only a a glossing over of the error.

    Of course there was the method of putting a USA telephone number into a 32 bit int. Before 1995, area code had a 0 or 1 as a middle digit, so if you made it the first digit, and then used the rest to make a 32 bit integer. The problem is that in 1995 numbers changed to have digits OTHER than 1 or 0 as the middle digit.

    Best laid plans of mice and men oft go astray.

  • Spoad (unregistered)

    I was once working on an embedded system which was outputting stored data by just dumping a block of memory out of a serial port, there was one part of each record which I could make head nor tail of at first until I finally worked out that the endianness was wrong and so was the bitwidth of what turned out to be a floating point number.

    I eventually decoded everything else and by a process of elimination realised it /had/ to be the 'last configured' timestamp... It turns out the PC application used to configure the device was written in Delphi and that is how Pascal stores its dates, as a floating point number of days.

  • RLB (unregistered) in reply to WhatEver

    IIRC it was Japanese before it was ISO.

  • Tse (unregistered)

    SAP ABAP dates are not stored or processed as integers. They are stored and processed as NUMCHAR values. Same for time. Also, if the module was installed as a part of the SAP system, the code would be both visible and debugable. Also, modifiable if you have the user rights and dev key to do so.

  • Matías Moreno (google) in reply to Spoad

    At least Pascal/Delphi uses 64-bit floats, nowadays this leaves about 40 bits to represent hours, minutes and seconds (even microseconds, without rounding errors / loss of precision) :-)

  • SAP developer (unregistered)

    The article is wrong about the way SAP ERP systems process dates. They don't use integers for dates. The date type is stored as a numeric character type with fixed length. It is processed as a date, not a number. For example, 20181001 - 1 equals 20180930.

  • Gerry (unregistered) in reply to Spoad

    IIRC this was chosen to be compatible with COM/Excel. Excel chose this to be compatible with Lotus 1-2-3

  • Wizofaus (unregistered) in reply to TheCPUWizard

    Fairly sure the type used to represent seconds in many iOS system calls and some Swift standard libraries is Double. Not sure how far in the future we'd need to be to get rounding errors as great as a whole day though.

  • (nodebb)

    Calling it now: They corrected by replacing all float values with double values, whose 53-bit mantissa is enough to hold any int value, and called it a day.

  • Martijn Lievaart (unregistered)

    @Little Bobby Tables: No I worked in the Netherlands in medical automation.

  • markm (unregistered) in reply to nate

    @Nate: I suspect that they did hit that bug during testing, but never noticed the output was wrong, because their automated check of the results also used float for the date, and whatever manual checking they did looked mainly at the formatting of the output rather than comparing dates. (99% of the time, formatting is more difficult to get right than the values).

  • i_like_speed (unregistered) in reply to WhatEver

    ISO8601 FTW

  • i_like_speed (unregistered) in reply to herby

    Agree on floating point being dangerous, and as a one-time developer for financial data providers e.g. data streamers that feed algo-traders (worked at two of them), there are NONE in the codebase that handles currency amounts.

  • notroot (unregistered) in reply to Foo AKA Fooo

    YYYYDDMM is not ISO 8601. You messed up the order of days and months. :D

Leave a comment on “A Floating Date”

Log In or post as a guest

Replying to comment #:

« Return to Article