Giter VIP home page Giter VIP logo

decimal's People

Contributors

alkis avatar djrodgerspryor avatar emerentius avatar fulara avatar haileys avatar jonathanstrong avatar markjr94 avatar mgeisler avatar nivkner avatar terrybrash avatar tonyfinn avatar trolleyman avatar vkalugin avatar zonyitoo 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  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  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  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

decimal's Issues

Two d128 values are equal, but their hashes aren't

Here's reproduction:

let d1 = d128::from_str("0.12342342000000000").unwrap();
let d2 = d128::from_str("0.12342342").unwrap();
assert_eq!(d1, d2); // Succeeds

let mut hasher1 = DefaultHasher::new();
d1.hash(&mut hasher1);
let h1 = hasher1.finish();

let mut hasher2 = DefaultHasher::new();
d2.hash(&mut hasher2);
let h2 = hasher2.finish();

assert_eq!(h1, h2); // Crashes on 'assertion failed: `(left == right)` left: `14437253609867582409`, right: `1217654567999082045`'

Error compiling library on Raspbian

I'm getting this error when compiling decimal-2.0.0 on Raspbian (armv7-unknown-linux-gnueabihf target):

error[E0308]: mismatched types
   --> /home/pi/.cargo/registry/src/github.com-1ecc6299db9ec823/decimal-2.0.0/src/dec128.rs:229:35
    |
229 |             decQuadToString(self, buf.as_mut().as_mut_ptr());
    |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^ expected u8, found i8
    |
    = note: expected type `*mut u8`
               found type `*mut i8`
    = help: here are some functions which might fulfill your needs:
            - .offset(...)
            - .wrapping_offset(...)

error[E0308]: mismatched types
   --> /home/pi/.cargo/registry/src/github.com-1ecc6299db9ec823/decimal-2.0.0/src/dec128.rs:230:39
    |
230 |             let cstr = CStr::from_ptr(buf.as_ptr());
    |                                       ^^^^^^^^^^^^ expected u8, found i8
    |
    = note: expected type `*const u8`
               found type `*const i8`
    = help: here are some functions which might fulfill your needs:
            - .offset(...)
            - .wrapping_offset(...)

error[E0308]: mismatched types
   --> /home/pi/.cargo/registry/src/github.com-1ecc6299db9ec823/decimal-2.0.0/src/dec128.rs:249:38
    |
249 |             decQuadToEngString(self, buf.as_mut().as_mut_ptr());
    |                                      ^^^^^^^^^^^^^^^^^^^^^^^^^ expected u8, found i8
    |
    = note: expected type `*mut u8`
               found type `*mut i8`
    = help: here are some functions which might fulfill your needs:
            - .offset(...)
            - .wrapping_offset(...)

error[E0308]: mismatched types
   --> /home/pi/.cargo/registry/src/github.com-1ecc6299db9ec823/decimal-2.0.0/src/dec128.rs:250:39
    |
250 |             let cstr = CStr::from_ptr(buf.as_ptr());
    |                                       ^^^^^^^^^^^^ expected u8, found i8
    |
    = note: expected type `*const u8`
               found type `*const i8`
    = help: here are some functions which might fulfill your needs:
            - .offset(...)
            - .wrapping_offset(...)

error: aborting due to 4 previous errors

It seems to happen because c_char on Linux ARM architecture is u8 instead of i8.

UB and usage of deprecated function

Found this crate via a a crater run (crater is a tool that runs a specific branch of rustc against locked dependencies of specific crates to figure out regressions in the compiler or in potential usages in applications).

This crate uses the std::mem:uninitliazed method which is not only deprecated but also could be unsound as per a similar advisory for another crate.

If you wish to continue maintaining it, it will be adisable to fix this issue and publish a new release. Else you could possibly hand it over to a new set of maintainers (can help you with that) or publish a note that it is abandoned/deprecated/won't be maintained in the future since it has around 10 open source crates that depend on it.

If you need any help in going about this, you can let us know

Thanks :)

Provide bindings to `decNumberRescale`

The decNumberRescale is more convenient than quantize in some situations where rounding is desired. It would be nice to support a rescale method on d128.

I'm not sure exactly how that would be bound to the C implementation, since there's no decQuadRescale function (only decNumberRescale).

d128 constants

Currently there is no way to have d128 constants in this library. I have worked around the problem by directly hard-coding values in and making the internal structure of d128 public. My current consts.rs looks like this:

pub const D0: d128 = d128{ bytes: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 34] };
pub const D1: d128 = d128{ bytes: [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 34] };
pub const D2: d128 = d128{ bytes: [2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 34] };

pub const DP5: d128 = d128{ bytes: [5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 7, 34] };

pub const D90: d128 = d128{ bytes: [26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 34] };
pub const D180: d128 = d128{ bytes: [138, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 34] };
pub const D200: d128 = d128{ bytes: [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 34] };

/// e
pub const DE: d128 = d128{ bytes: [98, 75, 23, 231, 90, 224, 213, 84, 68, 150, 46, 45, 132, 249, 255, 41] };
/// π
pub const DPI: d128 = d128{ bytes: [131, 230, 181, 218, 208, 98, 226, 180, 251, 179, 83, 235, 26, 204, 255, 45] };
/// π/2
pub const DPI2: d128 = d128{ bytes: [209, 231, 188, 113, 104, 49, 101, 236, 177, 246, 166, 233, 15, 239, 255, 37] };
/// φ
pub const DGOLDEN_RATIO: d128 = d128{ bytes: [56, 151, 199, 163, 186, 4, 185, 232, 97, 242, 238, 204, 128, 241, 255, 37] };
/// ∞
pub const DINFINITY: d128 = d128{ bytes: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120] };
/// -∞
pub const DNEG_INFINITY: d128 = d128{ bytes: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 248] };

However, I propose adding a d128::from_bytes function. It would take the raw bytes in as little endian, and convert to the system endianness.

impl d128 {
    #[cfg(target_endian = "little")]
    pub const fn from_bytes(b: [u8; 16]) -> d128 {
        d128{ bytes: b }
    }
    #[cfg(target_endian = "big")]
    pub const fn from_bytes(b: [u8; 16]) -> d128 {
        d128{ bytes: [b[15], b[14], b[13], b[12], b[11], b[10], b[9], b[8], b[7], b[6], b[5], b[4], b[3], b[2], b[1], b[0]] }
    }
}

Thoughts?

quantize() with quantum >1 doesn't work properly

Incorrect result when quantizing a d128 number to a quantum which is greater than one:

let a = d128::from(6361) / d128::from(10); // 636.1
let b = a.quantize(d128::from(100)); // b should be 600
println!("b should be 600, actually it is {}", b); // prints 636, WTF??

workaround:

let c = a.quantize(d128::from(1).scaleb(d128::from(2))); // workaround
println!("c should be 600, actually it is {}", c); // prints 6E+2 which is acceptable
println!("c should be 600, actually it is {}", c.quantize(d128::from(1))); // this one actually prints 600

sqrt method

A d128.sqrt() (like f64.sqrt()) method would be useful.

d128 to integer value

I need to round and fetch the integer equivalent of a d128 instance. There don't appear to be many ways to do this. The closest I've found is to use the Into trait implemented. Unfortunately, if the d128 value is too large, it fails and returns 0 without any way to signal error. Instead of using Into, the TryInto trait should be implemented to signal error. In addition, only u32 and i32 are accepted which are too small for my use case.

Implement std::hash::Hash on d128

This would greatly enhance the usability of this decimal type, and should not be too much trouble. The issue i was having was putting this type into a HashSet.

`from_str` panic

Using d128::from_str causes a panic when running in macOS 11.0.1 Big Sur (not on ARM).

Code:

use std::str::FromStr;
use decimal::d128;

fn main() {
  let x = d128::from_str("2");
  println!("{:?}", x);
}

Output:

bash-3.2$ RUST_BACKTRACE=1 cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.01s
     Running `target/debug/cpc`
thread 'main' panicked at 'attempted to leave type `context::Context` uninitialized, which is invalid', /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/core/src/mem/mod.rs:658:9
stack backtrace:
   0: rust_begin_unwind
             at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/std/src/panicking.rs:483
   1: core::panicking::panic_fmt
             at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/core/src/panicking.rs:85
   2: core::panicking::panic
             at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/core/src/panicking.rs:50
   3: core::mem::uninitialized
             at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/core/src/mem/mod.rs:658
   4: decimal::dec128::d128::default_context
             at /Users/kasper/.cargo/registry/src/github.com-1ecc6299db9ec823/decimal-2.0.4/src/dec128.rs:482
   5: decimal::dec128::CTX::__init
             at /Users/kasper/.cargo/registry/src/github.com-1ecc6299db9ec823/decimal-2.0.4/src/dec128.rs:26
   6: core::ops::function::FnOnce::call_once
             at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/core/src/ops/function.rs:227
   7: std::thread::local::lazy::LazyKeyInner<T>::initialize
             at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/std/src/thread/local.rs:304
   8: std::thread::local::fast::Key<T>::try_initialize
             at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/std/src/thread/local.rs:473
   9: std::thread::local::fast::Key<T>::get
             at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/std/src/thread/local.rs:456
  10: decimal::dec128::CTX::__getit
             at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/std/src/thread/local.rs:183
  11: std::thread::local::LocalKey<T>::try_with
             at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/std/src/thread/local.rs:271
  12: std::thread::local::LocalKey<T>::with
             at /rustc/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/library/std/src/thread/local.rs:248
  13: decimal::dec128::d128::with_context
             at /Users/kasper/.cargo/registry/src/github.com-1ecc6299db9ec823/decimal-2.0.4/src/dec128.rs:490
  14: <decimal::dec128::d128 as core::str::traits::FromStr>::from_str
             at /Users/kasper/.cargo/registry/src/github.com-1ecc6299db9ec823/decimal-2.0.4/src/dec128.rs:194
  15: cpc::main
             at ./src/main.rs:5
  16: core::ops::function::FnOnce::call_once
             at /Users/kasper/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/ops/function.rs:227
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

const literals?

How are folks dealing with the need to have const/static d128 literals? It seems like it might be possible these days to have the d128!() macro and things like zero() be const fn?

guidance on writing f64, f32 conversion

Hey - thanks for your work on this library. I'm using it for a project and interested in writing Into and possibly From for rust's primitive floats. However, my background is Python (and Decimal), not decNumber or C/C++ and I'm fairly new to Rust. Do you have any guidance on where to start? Is it simply a matter of bridging this library to functions that are already part of decNumber?

Incorrect formatting

It looks like d128 incorrectly interprets precision as width when printing values, for example:

let test: d128 = d128::from_str("123.12345678").unwrap();
print!("Should print 123.12345678, actual output: {:.8}", test);

This code prints 123.1234 instead of 123.12345678

compilation fails on ppc64le, s390x, aarch64, armv7hl

error[E0308]: mismatched types
   --> src/dec128.rs:229:35
    |
229 |             decQuadToString(self, buf.as_mut().as_mut_ptr());
    |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^ expected u8, found i8
    |
    = note: expected type `*mut u8`
               found type `*mut i8`
error[E0308]: mismatched types
   --> src/dec128.rs:230:39
    |
230 |             let cstr = CStr::from_ptr(buf.as_ptr());
    |                                       ^^^^^^^^^^^^ expected u8, found i8
    |
    = note: expected type `*const u8`
               found type `*const i8`
error[E0308]: mismatched types
   --> src/dec128.rs:249:38
    |
249 |             decQuadToEngString(self, buf.as_mut().as_mut_ptr());
    |                                      ^^^^^^^^^^^^^^^^^^^^^^^^^ expected u8, found i8
    |
    = note: expected type `*mut u8`
               found type `*mut i8`
error[E0308]: mismatched types
   --> src/dec128.rs:250:39
    |
250 |             let cstr = CStr::from_ptr(buf.as_ptr());
    |                                       ^^^^^^^^^^^^ expected u8, found i8
    |
    = note: expected type `*const u8`
               found type `*const i8`
error: aborting due to 4 previous errors

remove rustc-serialize

serde 1.0 has been around since over two years now, so I think one could think about removing rustc-serialize. Of course this is a breaking change so should wait until the next major release. I see you are doing major releases every now and then.

big-endian support

Currently libdecNumber.a is compiled with little-endian support. build.rs needs to detect big or little endian target architecture and pass DECLITEND=0 (for little) or DECLITEND=1 (for big).

Implement num traits for d128

Would it be possible to implement the Float, Zero and One traits from the num crate? I know some other libraries (e.g. nalgebra) use these as trait requirements for doing calculations, so implementing them for d128 means we can use the struct in other crates that require such traits.

Namely, this requires implementing all the trig functions and some extra math ones. I can see integer_decode and classify being tough to implement, though.

License question

The repo says the license is Apache 2.0, but the decNumber library seems to be GPL. Is it really possible to license this library as Apache 2.0?

`exp` causes infinite loop

It seems like the exp() method causes an infinite loop no matter what you give it. Example:

use decimal::d128;
fn main() {
  d128!(10).exp(d128!(0));
}

unsigned d128

Would you consider implementing an unsigned decimal type? I'm using d128 for some currency calculations, and I have a number of operations which only make sense with positive numbers.
I'd like to use an unsigned decimal type to enforce the use of positive numbers at compile time, rather than at runtime

sin() / cos() / tan() methods

The calculate crate would benefit from using d128 instead of f64 for calculating floats accurately. The ion shell uses calculate for it's built-in calc command. The methods above are required by calculate though, and are missing here.

status of the project

One maintainer of ion here. We have this issue, which is probably due to not merging the branch uninit-fix.
What is missing to get this merged?

Do you plan to get active again in the near future or would you be okay with a fork?

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.