-
Notifications
You must be signed in to change notification settings - Fork 23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add decimal to standard library #308
Comments
I did not say so in the first comment, but I'm willing to write this library or help others write it. |
Should be added to Fusion first but I cannot see how a library like this might be controversial, so I'm adding the "Accepted RFC" tag already. |
This caught my eye. |
Is by any chance a shorter variant like decimal64? I don't really require the bounds supported by decimal128 in my usecase so I temporary use https://gist.github.com/Araq/c71b764b94188337b24c6180b239229d |
Two reasons:
Also, although I say that I need not "store the number in the IEEE spec". On my first pass, I'm going to attempt that anyway. The number will literally only use up 128 bits of RAM if that works out to be reasonable. Likely a struct of four uint32. (My current library uses about 40+ bytes in a setup that is easy to use but wasteful of space.) I'm happy to share the workload if anyone is volunteering! |
The IEEE spec also defines a 64-bit and 256-bit version. Perhaps later on I could write a 64-bit version. Once the techniques are in place, it should be fairly straightforward. |
We should start with a module that contains the basics and then add more operations incrementally. No need to wait for a year. :-) |
Some time ago I created https://github.com/pigmej/nim-simple-decimal/blob/master/simpledecimal.nim which is really simple but may fulfill some basic reqs of someone (it's also based on some if Araq code) Anyway, having full blown decimal in std is must have I think. |
There is also https://github.com/Sud0nim/Decimal |
@Araq and others. This project is moving along faster than I thought. I might have a PR being made in the next 3 or 4 weeks. The first PR will support the basics and two math ops: addition and subtraction. The question: this project involves 2 parts: the So, should I create two PRs? Or, glom them both together into one? They are independent because the lexer/parser change is a proposed generic expansion of the language. Details: Currently, when you put a number into source code, the lexer insists on making it either an integer or floating literal. There is no way to support anything else. This change adds a new token: proc fooBar(num: string): string =
result = "foo " & num & " bar"
var a = 1234.56fooBar # the equivalent of: "1234.56".fooBar
assert a == "foo 1234.56 bar" Or, from the point of view of the decimals library which has import std/decimals
var a = 5192296858534827628530496329220095M # this number will not fit in u64
var b = 0.31415E1M |
Just a note to this thread: the part of this project that creates support for custom numeric literal suffixes to the compiler is mostly done. There will be upcoming tweaks of course. The suffixes will always have a single quote as part of the name. So, to update my earlier code, a decimal can be declared like such: import std/decimals
var b = 0.31415E10'm var amt = 12.9942'm(places=2) I will now start back on the main part: finishing the decimal library itself. |
Add decimal to standard library
Abstract
Adding a data type that provides support for decimal numbers (base 10 rather than base 2).
Motivation
Many programming languages have built-in support for decimal types and decimal math. This is because when writing programs that support numbers and both originate in base-10 math and are stored in base-10 math, converting to binary floating point number creates unwanted conversion errors between the numbering systems.
The most common types of programs that use decimal:
Some examples from other languages:
decimal
)One of the benefits of adding it to the standard library is possible compiler support as well. This is important for handling source-code literals. Details below.
Description
This would be a single 'decimal.nim' file added to the list of pure libraries that come with the compiler. A new
decimal
type is introduced and allows decimal storage and manipulation.Adding this to the standard library creates a common point of reference for other libraries and procedures that need to pass or receive decimal numbers with other libraries.
I recommend that the library store a big decimal number that can meet and conform to a public spec. Specifically, I recommend it meet IEEE 754-2008's 128-bit specification. I'm not suggesting that it store the number in the IEEE spec. Simply that it be designed to support:
That way, the decimal library could be used to export/import the IEEE spec.
One of the benefits of making it standard is possibly also better handling of decimal literals in source during compilation. For example, using a third party library, the following could be made to work:
but the following could not work:
This is because the compiler normally would convert the
123.456
into a floating point number before attempting to assign it. Thus, it introduces a base2-to-base10 conversion problem before the number is even stored.Four ways this could be handled:
the compiler "figures out" that it is trying to convert a sequence of digits for assignment to a decimal and passes in the value as a string despite the lack of quotes.
Support for a suffix, similar to the method seen in c#'s
m
is used. Thus,123.456m
is the same asnewDecimal("123.456")
.Generic support for number suffixes to be usable generically. So,
123.456m
becomesm"123.456"
. The decimal library would define a string template or proc form
.Compiler does nothing new and the decimal library simply fails if you attempt to assign a floating point number to it. In that case, this proposal is strictly a new library for the Nim standard library.
I strongly suggest option 3 as it also opens up possibilities for other uses.
BTW, two third-party decimal libraries of note; both based on the IEEE protocol:
https://github.com/status-im/nim-decimal
https://github.com/JohnAD/decimal128
The second one I wrote myself. Neither are really ready for inclusion in the standard library yet.
This project will take at least a year to complete.
Examples
Backward incompatibility
There would not be any backward incompatibility issues since decimal numbers are not currently supported by the language or it's standard library.
The text was updated successfully, but these errors were encountered: