Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
DEC64 (2014) (dec64.com)
64 points by tosh on June 22, 2019 | hide | past | favorite | 37 comments


Am I the only one who saw DEC in the title and got excited (perhaps a revival of the DEC Alpha 64 platform)?!?


"If you're not playing with 36 bits, you're not playing with a full DEC!" -Doug "DIGEX" Humphrey


Thanks, I came to the comments to verify it wasn't related to DEC the company or Alpha the architecture.


Previous: https://news.ycombinator.com/item?id=16513717

And that contains links to prior discussions


And especially the topmost comment by stephencanon (highlights):

https://news.ycombinator.com/item?id=16514962

"If you want a default decimal floating-point type, the only defensible choice is the decimal128 type standardized by IEEE 754. It has a fully-defined arithmetic, specified by experts who have spent their careers thinking about the issues involved, and is wide enough to exactly represent the US national debt in every currency used on earth.

There are situations where other decimal floating-point types are appropriate, but if you do not understand the tradeoffs you are making, you should be using decimal128."

and

"I would be remiss not to note that Intel has made available a well-tested complete implementation of IEEE 754 decimal64 and decimal128 under 3-clause BSD: http://www.netlib.org/misc/intel/ "


Dec64 is approachable to try to implement it on my own where it is needed the most (Java/JVM). decimal64/128 is most certainly not.


Can’t you link the existing C code by Intel, linked above and BSD licensed? There’s also GPL licensed one by IBM if you prefer that, linked in my other post.

No need to use the worse solution, which is dec64, unless you have some very specific goals.


"A later revision of IEEE 754 attempted to remedy this, but the formats it recommended were so inefficient that it has not found much acceptance. DEC64 is a better alternative."

This is just plain wrong. The IEEE decimal float types are now in SQL as DECFLOAT, coming to C and C++, I could go on...


> coming to C and C++

https://raw.githubusercontent.com/libdfp/libdfp/master/READM...

"libdfp

The "Decimal Floating Point C Library" User's Guide for the GNU/Linux OS and GLIBC 2.10+

Contributed by IBM Corporation Copyright (C) 2010 - 2014 Free Software Foundation"


I know one of the authors who worked on this; he described it as "decimal floating" because he insisted "there's no point".

Seems he was right: even IBM didn't do a hardware implementation after Power 6 IIRC.


Seems useful to me. Fixed sized data is very convenient for computers (fits in a register, pass-by-value), and being able to represent 0.1 and 0.01 is very convenient for humans.

The hardware does seem to be of questionable value; I heard rumours that the POWER hardware didn't actually beat the Intel software implementation running on an x86. That doesn't mean that the datatype is worthless.

And it sure as hell doesn't mean that this DEC64 type, which has arbitrarily incompatible parameters but adds nothing, and is late to the game, is better!


This looks absolutely beautiful (from a computer scientist, mathematician's and aestheticist's perspective)... Future typed programming languages should include this type!


Unfortunately this website doesn't talk much about the shortcomings of DEC64. Just to start, numbers in DEC64 have multiple representations, meaning even a simple equality check can take tens of cycles. Don't get me wrong, it's a cool way to store numbers, and it does have purpose, but it is not suited for general use like IEEE754 is.


I checked out the reference implementation and although there are some heuristics to make comparing numbers faster, you're completely right that the worst case scenario is quite complicated: https://github.com/douglascrockford/DEC64/blob/master/dec64....


That code is certainly not written by someone with x86 optimization experience. Using high-byte registers (e.g. ah which he rewrites as r0_h) is an awful idea on any Pentium Pro or more recent processor.


Alternatively: it was written by someone with obsolete x86 optimization experience.


IEEE754 also has multiple representations along with imprecise representations of integers, it’s limits (+Inf, -Inf, NaN) and simple decimals (0.1 + 0.2 != 0.3). For now, the biggest benefit is that we have hardware acceleration for IEEE754 everywhere, not that it is particularly good for any use case or that it is without weakness. But when we get FPGAs in commodity CPUs, the pros and cons value of IEEE754 change rapidly. Custom arithmetic formats could become more common.


And it’s reasons like this why I think IEEE 754 is beautiful in its own right.


The nan==nan bothered me


nan != nan severely bothers me, when it's the same object on both sides with exactly the same bit pattern. It's the work of imbeciles who are either unfamiliar with the concept of identity, or else don't understand why it's important and should be respected.


It feels like an argument between useful and correct.

Correct is "These two items are not numbers, so the numeric concept of equality can't be conclusively applied." This argument gives you NaN != NaN.

Useful is "We consider everything that's escaped the plane of numbers to be equivalent because they all require the same special handling." This gives you Nan = NaN.


> This argument gives you NaN != NaN.

That looks conclusive to me, though.

> This gives you Nan = NaN.

Problem is, there are multiple representations identified as "NaN". The question whether one NaN should be considered equal to another NaN is different from whether a NaN should equal to itself.

Whether a NaN is equal to a different NaN depends on the kind of equality; some equalities don't care about certain differences.

The C == equality allows the integer 1 to equal 1.0, in spite of a different representation; it is not simply a bitwise equality. (This happens by way of conversion of 1 to 1.0).

However, a thing should equal to itself under every applicable equality. That is non-negotiable.

There is a sense in which eq(x, x) can be false, if we consider argument passing to work by copy, and argument position to be part of identity. Then x is not x, because one is the left x and one is the right x they are in different stack locations or machine registers or whatever. Common Lisp allows for this kind of chicanery in its definition of "implementation identity" (embodied in its eq function). Numbers are not required to be eq, even to themselves. (eq 0 0) could yield false, the idea being that each copy of 0 could be a distinct object. Though that sort of stinks, it's not what is at pay here. These NaNs have type double, and ordinary values of that type are equal to themselves when copied to different argument positions of the equality operation.


Mentioned on the site:

> There are 255 possible representations of zero. They are all considered to be equal.


It's more than just zero. Every number can be represented in multiple ways in DEC64. For example, you could represent 3 as

3 x 10^0

or

30 x 10^-1


No, most numbers have only a single representation. A tenth have two, a hundredth have three, etc.


Small numbers with many representations are much more common than the full width ones.


This is true, but hardly important. Multiple representations hurt because they waste space, not because they're transiently evil.

If you're scared of normalizing before comparisons, or somesuch, nothing stops you normalizing around operations instead, like standard binary floats. Only you'd probably be shooting yourself in the foot, since you'd probably end up normalizing more and making the ‘integers are fast’ claim fail.


If you have to normalize DEC64 values, then the whole point of this format (1 cycle overhead for common “integer” operations on x64) evaporates.

(In fairness, for small integers, the operators over normalized values are closed — they always return normalized values)


That was my point, yes. Being unnormalized is a good thing. IEEE does the same thing for their decimals.

> (In fairness, for small integers, the operators over normalized values are closed — they always return normalized values)

Normally normalization refers to using the smallest possible exponent; in this light small integers are unnormalized.


No. Except for being decimal (and incidentally not implemented in most if not many architectures) it shares the same shortcoming with binary floating point numbers. [1]

[1] Note that this comment also applies to IEEE 754 decimal fp.


Why do you think IEEE-754’s decimal64 type falls short in those aspects?


This seems similar to the c#/ .net decimal type (1), except the .net type is 128 bits. The c# decimal precedes the IEEE decimal types and isn't the same.

(1) https://docs.microsoft.com/en-au/dotnet/csharp/language-refe...


Bad idea, better idea:

https://en.wikipedia.org/wiki/Logarithmic_number_system

main advantages:

- no multiple representations of the same number

- multiplication/division with complexity of addition and subtraction


LNS doesn’t seem to meet either of the goals of DEC64:

- Drop-in replacement for signed integer types for loop iteration, array indexes, etc (Exact integer operations for 56 (55?) bit addition and subtraction with 1 cycle overhead; similar efficiency for multiplication)

-Drop in replacement for financial fixed point types (which need to be exact in base-10)


Essentially just a base-10 version of floating point. It will work better for accountants and others performing conventional math done with base 10, but no fundamental advantage. The problem stems from trying to represent an uncountably infinite set with a finite set -- at the end of the day you end of with a very sparse approximation.


Dismissing it as "better for accountants" feels trivializes the problem.

There's billions of lines of code in circulation dealing with fixed-decimal currency formats.

The choices have always been:

* Scale things up and down (do your math in cents and convert back to dollars at the last minute), which is an easy opportunity for off-by-2-orders-of-magnitude bugs * Use floating points and pray nobody notices the all but guaranteed errors * Use something like BCD and have to explain it to everyone * Deal with some custom format or language-specific type, kissing portability goodbye, and depending on implementation, possibly poor performance

A well-established decimal-friendly type, whether this, decimal128, or something else, provides a go-to solution to a very common problem.


BCD has been around since the earliest CPU's. I get the importance of using base 10 for finances, but there is nothing new offered here that I can see.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: