Skip to content
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

BigInt's #347

Closed
nivida opened this issue Apr 17, 2019 · 9 comments
Closed

BigInt's #347

nivida opened this issue Apr 17, 2019 · 9 comments

Comments

@nivida
Copy link

nivida commented Apr 17, 2019

Description

I'm working in the blockchain world as a developer and we have to handle security-sensitive and FinTech related data. This is the reason why Deno could be interesting for the usage with DApp's.

We have currently a discussion over several projects because of the coming BigInt and the current solutions to represent BigIntegers in JS.

Feature Request

My idea would be that Deno could provide more real types with their provided std lib.
The types could be implemented with WASM or JS.

Possible types

  • BigDecimals
  • FixedBigInt
  • BigInt
  • ...

References

@zekth
Copy link
Contributor

zekth commented Apr 17, 2019

Really interesting feature. I'd enjoy working on this.
I think the choice between WASM or Ts would be the benchmarks. Do you have an example of common operation that can be bottlenecked with Ts ? I can see the tests in your refs but no bench that's why i'm asking.

@axetroy
Copy link
Contributor

axetroy commented Apr 22, 2019

BigInt only supports integer

But maybe we can make it support float in a clever way.

@axetroy
Copy link
Contributor

axetroy commented Apr 22, 2019

I tried to implement it with BigInt, it is feasible for me.

function split(numeric: string): string[] {
  const [_, integer, float] = /(\d+)\.?(\d+)?/.exec(numeric);
  return [integer || '0', float || '0'];
}
export type Action = 'plus' | 'minus';

export class Big {
  constructor(private value: string) {}
  public calc(a: string, b: string, type: Action): string {
    let [integer1, float1] = split(a);
    let [integer2, float2] = split(b);

    const maxIntegerLen = Math.max(integer1.length, integer2.length);
    const maxFloatLen = Math.max(float1.length, float2.length);

    integer1 = integer1.padStart(maxIntegerLen, '0');
    float1 = float1.padEnd(maxFloatLen, '0');

    integer2 = integer2.padStart(maxIntegerLen, '0');
    float2 = float2.padEnd(maxFloatLen, '0');

    const srcBigInt = BigInt(integer1 + float1);
    const destBitInt = BigInt(integer2 + float2);

    const maxLength = Math.max(
      (integer1 + float1).length,
      (integer2 + float2).length
    );

    let result = '';
    switch (type) {
      // a + b
      case 'plus':
        result = (srcBigInt + destBitInt).toString();
        break;
      // a - b
      case 'minus':
        result = (srcBigInt - destBitInt).toString();
        break;
    }

    result = result.padStart(maxLength, '0');

    const integer = result.substr(0, maxIntegerLen);
    const float = result.substr(maxIntegerLen);
    this.value = integer + (+float ? '.' + float : '').replace(/0$/, '');
    return result;
  }
  public plus(numeric: string) {
    this.calc(this.value, numeric, 'plus');
    return this;
  }
  public minus(numeric: string) {
    this.calc(this.value, numeric, 'minus');
    return this;
  }
  public toString() {
    return this.value;
  }
}

// calculate float
console.log(new Big('1.2').plus('0.2')); // Big { value: "1.4" }
console.log(new Big('1.234').plus('0.2')); // Big { value: "1.434" }
console.log(new Big('0.3').minus('0.1')); // Big { value: "0.2" }
console.log(new Big('100.1').plus('1000.123')); // Big { value: "1100.223" }

// calculate normal integer
console.log(new Big('1').plus('2')); // Big { value: "3" }
console.log(new Big('15').plus('21')); // Big { value: "36" }
console.log(new Big('1001').minus('1')); // Big { value: "1000" }
console.log(new Big('1001').plus('999')); // Big { value: "2000" }

// calculate big integer
const maxInteger = Number.MAX_SAFE_INTEGER; // 9007199254741091
console.log(new Big(maxInteger + '').plus('1.1')); // Big { value: "9007199254741092.1" }

There is a problem with this, do we need to write a library of high-precision calculations in std?

I think there should be.

High-precision calculations make deno more widely used and can be applied to blockchain/Machine learning technology and more.

If @ry agree with this, I am happy to work on it.

Update

this approach is not feasible. Ignore it.

@zekth
Copy link
Contributor

zekth commented Apr 22, 2019

@axetroy what about make class Big and BigInt extends Big and BigFloat extends Big ? For example you have more operation for Floats, and if you're only using Int it would be slow down due to the float handling.

@axetroy
Copy link
Contributor

axetroy commented Apr 23, 2019

@zekth

BigInt extends Big doesn't make sense.

If you only need integer calculations, why not use BigInt

@hayd
Copy link
Contributor

hayd commented Apr 23, 2019

Is this available in v8?

cc @kevinkassimo

@kevinkassimo
Copy link
Contributor

kevinkassimo commented Apr 23, 2019

@hayd the V8 version Deno using already comes with BigInt

@zekth
Copy link
Contributor

zekth commented Apr 23, 2019

@zekth

BigInt extends Big doesn't make sense.

If you only need integer calculations, why not use BigInt

True.

@axetroy
Copy link
Contributor

axetroy commented May 24, 2019

Using big module in here

import { Big } from 'https://deno.land/x/math/mod.ts';

new Big(0.1).plus(0.2).toString(); // '0.3'
console.log(0.1 + 0.2); // 0.30000000000000004

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants