Live data from Hacker News

BigInt Shipping in Firefox

wingolog.org

131–140 of 172 posts

Re: BigInt Shipping in Firefox

#131
post #119

Earlier quoted context omitted.

I think stuff like wolfram language and mathematica probably have some "universal" numeric type. However, I don't know a single mainstream application programming language that has a single numeric type that can handle: arbitrarily large integers, floating point values, and correct decimal arithmetic (0.1 + 0.2 == 0.3). I have at least a passing familiarity with probably about a dozen general purpose programming lang…

How odd to notice that my brain really messed that number type up. I could swear Python has a type called (capitalized) Number and that this handles arbitrarily large numbers as well as decimals. Seems like that 'memory' is completely fictional.

Python does actually have an abstract type for numbers, and it is called Number: https://docs.python.org/3/library/numbers.html.

Re: BigInt Shipping in Firefox

#132
post #19

Here is the proposal[0]. There are important real use cases for this. I authored an implementation of the FNV64 hash function[1] at my last job. I needed to use the BigInteger.js[2] library. It truly surprised me that Javascript in 2018 did not support something so simple as 64-bit integers. [0]: https://tc39.github.io/proposal-bigint/ [1]: https://golang.org/src/hash/fnv/fnv.go [2]: https://github.com/peterolson/Big…

Yeah - plus Javascript doesn't even support 32 bit integers.

The implementations usually do (in the sense of optimizing them)

Re: BigInt Shipping in Firefox

#133
post #92

can it represent and manipulate ipv6 addresses (128 bit quantities) efficiently? not having to split into two 64 bits or deal with them as bit-strings may be an improvement for some things

Internally it is implemented by spliting the number into an array of conveniently sized chunks (traditionally called limbs). That might mean either the machine word size for optimized assembly implementation on many common platforms or one bit less than native word size for portable C implementation (and architectures without carry flag) or some fixed number like 15 bits (IIRC mbedTLS has or at least used to have hardcoded limb size of 15bits in its bignum implementation).

Re: BigInt Shipping in Firefox

#134

BitInt's "n" suffix appears to stand for "numeric", but that seems confusing when typeof 1 === "number" and typeof 1n === "bigint" . Why not an "i" suffix for "integer"? I understand that a "b" suffix is probably reserved in case JavaScript adds support for binary literals. https://tc39.github.io/proposal-bigint/#prod-BigIntLiteralSu...

I suspect it is more that in mathematics, n is used to indicate integer values as opposed to for example x, which is used with real values.

Re: BigInt Shipping in Firefox

#135
post #126

Earlier quoted context omitted.

> Do you really expect I mentioned this example, mentioned I wrote some code that solves this issue, and still never looked up or came across an explanation of why most programming languages behave this way? Well, what you described does not actually solve the issue despite you claiming that it has, so I thought you might be confused. Which is not an insult -- many people are confused about this issue. And you appear…

> Your "fix" makes it so that 1/10 + 2/10 == 3/10, but it still doesn't make it so that 1/3 + 1/3 == 2/3. So how is it actually "precise"? Fair point! I don't think anyone ever put it quite this way. I mean, I knew that 1/3 cannot be represented in decimal and that decimal, like binary, is imprecise for the exact same reason, but I don't think anyone asked me about the definition of precise and why I think my version…

> I think the answer is that, in code, we type in decimal: 0.1+0.2

I think you are exactly right. People think of decimals as being the "actual", "primary", "fundamental" numbers, and binary as being an imperfect representation of those. Whereas in reality, both binary and decimal are imperfect representations of rational numbers, and we only think of decimal as being more fundamental because of our writing system.

> Fair enough about floats, but why about arbitrarily large integers

How exactly would you represent them? The best way I can think of is:

    struct BigInt {
        int64_t first_64;
        char *data; // pointer to extra, dynamically allocated data
        int data_len;
    };
This would allow you to avoid doing a dynamic allocation for the most common case of being under 64 bits. And the addition algorithm would probably special case that too, and look something like this:

    BigInt add(BigInt x, BigInt y) {
        if (x.data_len == 0 && y.data_len == 0) {
            int64_t new_val = x.first_64 + y.first_64;
            if (overflow_signaled()) {
                return add_slow_path(x, y);
            }
            return {new_val, 0, nullptr};
        } else {
            return add_slow_path(x, y);
        }
    }
As you can see, there is a ton of complexity here, even just for the simplest possible case. Replacing what was before literally just one instruction, e.g. addq %rbx, %rcx . Also, each number is represented by a 20-byte struct now instead of 8. So now each 64-byte cache line can fit only 3 values instead of 8. Because of all this, it would be dramatically slower.

This is just for the easiest case of no overflow! If you overflow and have to then go allocate memory dynamically and loop over it, it would of course be even worse.

Re: BigInt Shipping in Firefox

#136
post #47
post #43

Kind of bummed this is a new primitive type. Every instance of `typeof a === 'number'` just became `typeof a === `number` || typeof a === 'bigint'`... EDIT: The more I think about it (and the more comments I get), the more I think this might actually be a good thing. I think bigint will probably not be used in places where integer numbers are currently used, and it might be unreasonable to expect code to work with nu…

To be fair, it really shouldn’t be conflated with ‘number’ - it isn’t the same thing, the behavior differs. And you can (and probably should) use small helper functions for these kinds of checks, pretty much for this kind of flexibility. Kind of curious what other libs (like lodash) will do.

I'm still holding out for an int type, I use a double about once a year but I'm completely insecure about using integer operations (e.g. div, mod, as an offset-based index) in javascript.

Re: BigInt Shipping in Firefox

#137
post #117

Earlier quoted context omitted.

JavaScript can't easily evolve past the optimization tricks used in the major implementations. They all heavily rely on NaN tagging which makes 64-bit value types problematic. For similar reasons the architecture of V8 in particular has effectively dictated the design of WebAssembly, especially regarding control flow constructs like goto and coroutines.

> For similar reasons the architecture of V8 in particular has effectively dictated the design of WebAssembly, especially regarding control flow constructs like goto and coroutines. The weirdness of WebAssembly with regards to control flow constructs is rooted in Emscripten's "relooper", which was developed in a naive manner ignoring previous (superior) research on irreducible control flow.

Yes, but in both cases this is because the JS runtimes (v8 in particular) makes it really difficult to feel okay with unconstrained control flow. The relooper may have been an influence but it was primarily pressure from the v8 people (I was in these meetings)

I'm less certain on my memory but I recall that Spidermonkey was more easily able to do fancier things with control flow.

Re: BigInt Shipping in Firefox

#139
post #69

Earlier quoted context omitted.

I think they were making a joke.

Obviously it was some degree of tongue-in-cheek, but I’m not really that amused, to be honest. It needs a leftpad reference or something.

Anybody who thinks that's actually good (or even real) advice is going to write horrible code regardless, IMHO.

Re: BigInt Shipping in Firefox

#140

Earlier quoted context omitted.

> For similar reasons the architecture of V8 in particular has effectively dictated the design of WebAssembly, especially regarding control flow constructs like goto and coroutines. The weirdness of WebAssembly with regards to control flow constructs is rooted in Emscripten's "relooper", which was developed in a naive manner ignoring previous (superior) research on irreducible control flow.

Yes, but in both cases this is because the JS runtimes (v8 in particular) makes it really difficult to feel okay with unconstrained control flow. The relooper may have been an influence but it was primarily pressure from the v8 people (I was in these meetings) I'm less certain on my memory but I recall that Spidermonkey was more easily able to do fancier things with control flow.

I worked at Mozilla Research in the early days of Asm.js and sat next to that team. I would frequently tell them that they should support arbitrary control flow, and that there were better ways to achieve it with Emscripten than the Relooper. There wasn't much interest in improvements at the time, although it appears that the LLVM WebAssembly backend now uses a better approach.

While SpiderMonkey itself might support fancier things with control-flow, they were writing a separate compiler for Asm.js that relied on structured control flow for SSA construction, but I have no experience with how things evolved after that. Reading the thread at https://github.com/WebAssembly/design/issues/796, it seems that V8 and SpiderMonkey have roughly equivalent design constraints.

Post reply on HN