douglascrockford / dec64 Goto Github PK
View Code? Open in Web Editor NEWDecimal floating point
Decimal floating point
DEC64: Decimal Floating Point Douglas Crockford [email protected] dec64.com 2022-09-07 Public Domain NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. SUBJECT TO CHANGE WITHOUT NOTICE. DEC64 is a decimal floating point format for the next generation of application programming languages. dec64.asm is an implementation of the elementary operators for x64 processors. dec64.s is an implementation of the elementary operators for ARM64 processors. dec64.obj.html is a description of the functions in dec64.asm and dec64.s. dec64.h is a companion header file for C. dec64_test.c is a test program. dec64_string.c is an implementation of functions for converting between DEC64 and strings. dec64_string.html is a description of the functions in dec64_string.c. dec64_string.h is a companion header file. dec64_string_test.c is a test program. dec64_math.c is a placeholder implementation of elementary functions. Many of these function are not accurate enough or fast enough. It should be replaced with a better implementation. The functions include acos asin atan atan2 cos exp factorial log raise root sin sqrt tan and random seed dec64_math.html is a description of the functions in dec64_math.h. dec64_math.h is a companion header file. dec64_math_test.c is a test program. dec64.html is a descriptive web page. dec64.png is a logo. Vadim Pisarevsky has prepared a C++ version that can be found at https://github.com/vpisarev/DEC64/tree/alt A NASM port of dec64.asm is available at https://gist.github.com/jamesdiacono/bc9337520727876e09bafaf98225019c, which passes the tests on Linux and MacOS.
For some inputs dec64_sqrt
can enter an infinite loop where it will not converge on a result and will instead oscillate between two values forever. It seems to be related to rounding behavior within dec64_divide
. Printing both the coefficient and the exponent of progress
, we get the following log from dec64_sqrt(dec64_make(36040, 0))
9011000000000000 -12
4507499778049051 -12
22577476706966965 -13
11368552409916279 -13
5842783632731283 -13
3229806454536597 -13
2172831395833602 -13
19157483389377885 -14
18984987616317365 -14
1898420397630861 -13
18984203960134855 -14
1898420396013486 -13
18984203960134855 -14
1898420396013486 -13
18984203960134855 -14
1898420396013486 -13
18984203960134855 -14
1898420396013486 -13
18984203960134855 -14
1898420396013486 -13
...
Would it be possible to add compile instructions for this project?
Could you document how rounding works with DEC64? I've only found this:
; Rounding is to the nearest value. Ties are rounded away from zero. Integer
; division is floored. The result of modulo has the sign of the divisor.
; There is no negative zero.
And how about other sources of approximations (at least all those mentioned in vlang/v#5180 (comment) )? How they're handled in DEC64?
I was having a conversation with a friend about DEC64, and he brought up the "decimal64" IEEE format, and now I feel the need to ask...
https://en.wikipedia.org/wiki/Decimal64_floating-point_format
How are these two formats (DEC64 versus decimal64) related, and how would I go about convincing somebody that one is better than the other?
(On record, IBM had started implementing decimal64 directly into their hardware not long after the format was formally specified.)
Would it be possible to release a reference implementation of dec64.asm in C?
dec64_sin() doesn't check for radians values of magnitude large enough that subtracting or adding 2*pi doesn't change it; for such values dec64_sin() will never return.
Simple methods of reducing radians may be so inaccurate as to give a meaningless result for large magnitudes. Looks like there is a way around that (http://www.csee.umbc.edu/~phatak/645/supl/Ng-ArgReduction.pdf), though ultimately radians may be the result of a calculation which itself is subject to error and has a result where the next larger and next smaller DEC64 number are a significant fraction of 2_pi or even vastly more than 2_pi apart--in that case can one really claim to be able to calculate the sine accurately?
(Speaking of argument reduction--you can reduce it to between -pi/2 and pi/2; that should give a more accurate result with the Taylor series.)
I found this while trying to diagnose #32.
#define D64(x, y) (((x) << 8) | ((y) & 0xFF))
dec64 a = dec64_divide(dec64_new(36040, 0), D64(1898420396013486ULL, -13));
dec64 b = dec64_divide(dec64_new(3604, 1), D64(1898420396013486ULL, -13));
The values of a and b will be different (18984203960134854e-14 and 18984203960134855e-14 respectively) despite the inputs being the same number but with different representations. I have to use D64
here to create the second value because dec64_new
will change the value in such a way that it breaks this reproduction of the bug. The value can be obtained through only calls to dec64_divide
, dec64_add
, and dec64_new
.
Hi, I am implementing my own programing language, I am at that point where I can choose the number representation. Right now I have tested fixed point numbers and was surprised how fast they are, basically no benchmark shown any difference from plain ints. That's with gcc -O3 or clang -O2. Without the optimisation switch, speed is 5-100 worse depending on the compiler / optimisation (TinyC is very slow on this).
Now I want to try DEC64, but I do not want to use assembly at the moment. Do you happen by any chance to have a plain C implementation at least for basics (i. e. convert to/from int/double, add/multiply)? Or was your first prototype built in asm from the very beginning?
Other question is about 64 bits, I can only use 63 bits, because I need one bit for pointer tagging for the VM. What would be a solution here (for DEC63), reduce the magnitude bits?
Also I use this chance to thank you for the example TDOP compiler you have here, reading it's code and related text inspired me very much!
From all the tests in test_all_new
function from dec64_test.c
Only one is not an exact match of the expected dec64 number. (line 1123).
test_new(-368934881474191049, 0, (-368934881474191 << 8) + 3, "-368934881474191049");
I'd like to suggest to change the expected number to the exact match and remove the compare-with-normalise step in judge_not
.
I believe it will help readers to understand how the dec64_new
function works. In my personal case it took me some time to realise that the normalisation step was there, just for one case. But perhaps I'm missing something.
As part of the dec64_sin
function, the first operation is to move the input (radians
) into the range (-pi, pi)
. However, this is implemented through repeated subtraction and addition. On large inputs this can cause dec64_sin
to take a very long time to bring the argument into range or forever for huge inputs where the addition and subtraction have no effect due to loss of precision. There are several algorithms that exist for doing argument reduction in a reasonable time on such inputs - "Argument Reduction for Huge Arguments: Good to the Last Bit" is a good, if old, source.
Something like this (perhaps with optional new
)
x = new Dec64(0.1)
y = new Dec64(0.2)
z = x + y
console.log(z) // 0.3
Could be useful for the brave including those of us who experiment with creating new languages that compile to JavaScript. I see Rust has adopted dec64 already.
Cheers!
### Motivation
Statistical computations, financial computations, simulations, statistical proving systems (e.g. diehard, dieharder, STS, ...), etc. need provably unbiased rounding. Unfortunately DEC64 uses e.g. biased rounding and thus is not suitable for these domains which seems to non-negligibly limit its use.
### Proposal
Create a separate DEC64-based standard DEC64unbiased
, which will provide all functionality as DEC64, but will also guarantee unbiased computation (especially rounding) by employing the Alternating tie-breaking technique or alike (though I don't know of any other providing this guarantee - all others are just converging to the optimum, but they do not guarantee anything).
### Alternatives considered
2. Changing DEC64 so that it provides "rounding modes". Not viable as any modality (modes, options, ...) proved problematic - at least with IEEE 754 etc. The goal is to have something fixed without any way to "get astray".
Attached: math_test.txt
Using vs2017 Pro
Surprised this is missing since it's the famously known javascript which dec64 is supposed to solve.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.