Git Product home page Git Product logo

decimal128's People

Contributors

johnad avatar pmunch avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

Forkers

pmunch ardek66

decimal128's Issues

Thread safety

Just a quick reminder that it might be necessary to use this library in a multithreaded context for example for accounting software with work split across one core per year.

In that case trivial types like arrays should be preferred over sequences if possible, for example here:

proc decode10bitDPD*(dpd: uint16): seq[byte] =
# decode the 3 digits from a densley packed binary of the first 10 bits
# returns 3 bytes containing the digits
# original code from:
# https://github.com/wd5gnr/DensePackDecimal/blob/master/dpd.c
const
FIRST_CHUNK = 0x380.uint16
SECOND_CHUNK = 0x70.uint16
THIRD_CHUNK = 0x7.uint16
var x: uint16 = 0
var y: uint16 = 0
var z: uint16 = 0
if nz(dpd and 8):
if (dpd and 0xE) == 0xE:
case (dpd and 0x60):
of 0:
x = 8 + ((dpd and 0x80) shr 7)
y = 8 + ((dpd and 0x10) shr 4)
z = ((dpd and 0x300) shr 7) or (dpd and 1)
of 0x20:
x = 8 + ((dpd and 0x80) shr 7)
y = ((dpd and 0x300) shr 7) or ((dpd and 0x10) shr 4)
z = 8 + (dpd and 1)
of 0x40:
x = (dpd and 0x380) shr 7
y = 8 + ((dpd and 0x10) shr 4)
z = 8 or (dpd and 1)
of 0x60:
x = 8 + ((dpd and 0x80) shr 7)
y = 8 + ((dpd and 0x10) shr 4)
z = 8 + (dpd and 1)
else:
echo "should never happen (A)"
else:
case (dpd and 0xE):
of 0x8:
x = (dpd and 0x380) shr 7
y = (dpd and 0x70) shr 4
z = 8 + (dpd and 1)
of 0xA:
x = (dpd and 0x380) shr 7
y = 8 + ((dpd and 0x10) shr 4)
z = ((dpd and 0x60) shr 4) or (dpd and 1)
of 0xC:
x = 8 + ((dpd and 0x80) shr 7)
y = (dpd and 0x70) shr 4
z = ((dpd and 0x300) shr 7) or (dpd and 1)
else:
echo "should never happen (B)"
else:
echo "clean"
x = (dpd and FIRST_CHUNK) shr 7
y = (dpd and SECOND_CHUNK) shr 4
z = (dpd and THIRD_CHUNK)
echo "xyz " & $x & " " & $y & " " & $z
result = @[x.byte, y.byte, z.byte]

This also avoids memory allocation which might be a bottleneck if done regularly and which is also problematic for long-running processes as it might lead to memory fragmentation.

arithmetic operator functions are missing

  • == Equality. Specifically, an equality check that ignores significant digits. For equality checks that take significance into account, there is already the === operator.
  • != Not Equality.
  • + Addition.
  • - Subtraction.
  • * Multiplication.
  • / Division.
  • div Integer Division.
  • mod Modulo.
  • < Less-than.
  • <= Less-than-or-equal.
  • > Greater-than.
  • >= Greater-than-or-equal.

While encoding/decoding and simple import/export from native data types is supported, the basic ability to do math with the library is missing.

These functions cannot resort to simply converting to either float64 or int64 since those types lack both the precision and the needed scale for the math to properly work.

I've started a document that explains, in the context of this library, how significance and rounding should be handled. See https://github.com/JohnAD/decimal128/blob/master/explaining-op-significance.rst I'm not a mathematician and all coments are welcome regarding it.

DPD support not complete

While I have written some of the (Densely Packed Decimal) DPD code for storing the coefficient, it is far from tested. At the moment, attempts to encode or decode using that technique will raise an error.

general announcement: adding decimal to Standard library

See nim-lang/RFCs#308

I'm planning on adding generic decimal type to the standard library and have general approval. As such, this project will very likely disappear (eventually) in deference to that one. I plan on still supporting the ideas of this library, including accurately supporting significance and scale/precision.

As a bonus, I'm going to attempt to support the IEEE spec natively as well: the variable will only use 128bits of RAM instead of the big variant type this one uses.

Universally add optional "precision" and "scale" parameters to newDecimal128

  • newDecimal128(string)
  • newDecimal128(int)
  • newDecimal128(float)
  • add getPrecision
  • add getScale
  • add setPrecision (returns a new Decimal128)
  • add setScale

This issue came from the discussion in issue #1

For each of the newDecimal128([T]) procs, add two optional parameters:

precision to set the absolute precision of the decimal, regardless of what is seen in the incoming number. That is, this will artificially set the number of significant digits. Any value greater than 34 is treated as 34.

scale to set the precision of the decimal, regardless of what is seen in the incoming number, to enable a fixed number of decimal places of the fractional part. This can be a negative number, though that is not a common use of it.

Example:

assert $newDecimal128("43.2") == "43.2"
assert newDecimal128("43.2").getPrecision == 3
assert newDecimal128("43.2").getScale == 1

assert $newDecimal128("43.2", precision=5) == "43.200"
assert newDecimal128("43.2", precision=5).getPrecision == 5
assert newDecimal128("43.2", precision=5).getScale == 3

assert $newDecimal128("43.2", scale=2) == "43.20"
assert newDecimal128("43.2", scale=2).getPrecision == 4
assert newDecimal128("43.2", scale=2).getScale == 2

assert $newDecimal128("43.2", scale=-1) == "4E+1"
assert newDecimal128("43.2", scale=-1).getPrecision == 1
assert newDecimal128("43.2", scale=-1).getScale == -1

Any rounding is based on bankers rounding aka "round-up-to-even".

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.