
LibBF – a small library to handle arbitrary precision floating point numbers - gbrown_
https://bellard.org/libbf/
======
abetusk
For those that don't know, Fabrice Bellard is the author of ffmpeg [1], the
tiny c compiler (tcc) [2], linux in the browser [3] among many others [4].

Does anyone know how LibBF stacks up against GMP? [5]

[1] [http://ffmpeg.org/](http://ffmpeg.org/)

[2] [https://bellard.org/tcc/](https://bellard.org/tcc/)

[3] [https://bellard.org/jslinux/](https://bellard.org/jslinux/)

[4] [https://bellard.org/](https://bellard.org/)

[5]
[https://en.wikipedia.org/wiki/GNU_Multiple_Precision_Arithme...](https://en.wikipedia.org/wiki/GNU_Multiple_Precision_Arithmetic_Library)

~~~
lsb
Yes, a comparison with GMP is the first link:
[https://bellard.org/libbf/benchmark.html](https://bellard.org/libbf/benchmark.html)

~~~
Sean1708
Is there a comparison for anything other than multiplication? Or is
multiplication fairly representative of other operations on AP numbers?

------
danbruc
Mostly off topic but maybe this post attracts people who know the answer to a
question that I ran into when I implemented a big integer based rational
number library some time ago.

The decimal representation of a rational number p / q has the general form
±<integer part>.<non-repeating fractional part>(<repeating fractional part>),
for example 41,111,111 / 333,000 equals 123.456(789). Is there an efficient
algorithm to determine the lengths of the fractional parts or one that does at
least provides reasonably tight bounds on them?

I did quite a bit of research at the time but only with limited success. I am
reasonably sure that finding the exact lengths is comparable in hardness to
factoring p and q in some cases and possibly harder in the general case. But I
did not come across much with regard to bounds on the lengths.

Maybe there was somewhere an implicit answer to my question which I did not
recognize or fully appreciate due to my limited knowledge of number theory but
I never came across an explicit statement that said that printing the decimal
representation of a rational number or estimating its length is a hard or
unsolved problem.

I ended up just performing the expansion digit by digit until I detected a
cycle or reached a specified maximum length, but it would by nice to know in
advance how long it will be or at least to learn that this is actually an hard
or unsolved problem.

~~~
mrmr1993
As you said, this is equivalent to factorisation in terms of complexity. The
Wikipedia article[0] on the subject does a good job of summarising the details
of this in the section "Other properties of repeatend lengths".

For a simple answer, the lengths are bounded above by Euler's totient function
[1] (the sum of factors) of the denominator. Any tighter bounds depend on the
specific primes in the factorisation.

Note that Euler's totient function is "always 'nearly n'" in magnitude (Hardy
and Littlewood), so that representation will be very expensive for most
fractions of large denominator.

[0]:
[https://en.wikipedia.org/wiki/Repeating_decimal](https://en.wikipedia.org/wiki/Repeating_decimal)
[1]:
[https://en.wikipedia.org/wiki/Euler%27s_totient_function](https://en.wikipedia.org/wiki/Euler%27s_totient_function)

~~~
danbruc
That Wikipedia article on repeating decimals is probably where I started
looking into it, but the article is somewhat weird. For many problems
Wikipedia articles say we know this and that but those other things are still
unknown, this article has a lot of information but does not talk about unknown
things at all. The length of the repeating fractional part of 1 / n divides
φ(n)...and then nothing. Is this all we know or is there more but just not in
this article?

I still remember that quite well because that was probably the first and only
time that I was unable to find someone stating that we do not know any better,
and not only the Wikipedia article but everywhere I looked there was no such
statement to be found. I eventually gave up after a couple of evenings but it
obviously kept stuck somewhere in my mind and that is why I wrote the initial
comment.

~~~
jcranmer
MathWorld is often a decent resource for finding this kind of information:
<[http://mathworld.wolfram.com/DecimalPeriod.html>](http://mathworld.wolfram.com/DecimalPeriod.html>),
but it's often difficult to arrive at those pages if you don't have any idea
where to start.

~~~
danbruc
I certainly also looked through MathWorld but I failed to make some - in
hindsight - rather obvious connections or did not pay enough attention. I
certainly knew what the discrete logarithm problem is and that it is hard but
I did not realize until a few minutes ago that finding the multiplicative
order is just that only with a different name. And now being aware of that the
MathWorld article spells exactly this out in a way that it seems impossible to
miss.

------
peatmoss
Perhaps a side digression to this conversation, but... in spite of all the
cool languages we talk about that have many on-paper advantages of either
safety, convenience, or support of paradigms, is there really any option
besides C for this kind of thing?

It still seems that, if you want to write Core Infrastructual Code that can be
run anywhere, on anything, that links with any other software without any
caveats, disclaimers, or compromise, C is still king.

Could this have practically been written in rust? haskell? ...and still have
the same degree of embeddability and reach?

~~~
isaachier
In my limited experience, no. All of the languages you mention put developer
experience above portability, so usually require a basic runtime. C on the
other hand is not interested in saving you from the machine, which allows for
extremely minimal programs. Even C++ isn't great here compared to C. Then
again, debugging segfaults isn't for everyone, so most are fine giving up C.

~~~
whyever
> All of the languages you mention put developer experience above portability,
> so usually require a basic runtime.

Rust's runtime is comparable to C's. It is less portable because it uses LLVM
as a backend, not because of the runtime.

> Then again, debugging segfaults isn't for everyone, so most are fine giving
> up C.

Depending on the application, having vulnerabilities due to undefined behavior
is a much bigger problem than having to debug segfaults.

~~~
nomonomus
then port it to gcc?

~~~
steveklabnik
We’d love to see a gcc front end for Rust. Someone attempted one in the
pre-1.0 days, which was... not simple. Someone has to step up and do it
though.

------
SloopJon
For Mac users trying this at home, I made the following changes to build and
run the tinypi tests on Sierra:

1\. Comment out the malloc.h include in tinypi.c.

2\. Add -Wno-unused-function to CFLAGS.

3\. Use shasum, rather than sha1sum, in the test target.

~~~
wnoise
Having malloc.h as an include is bizarre, anyway. The standard location for
malloc and related functions is stdlib.h, and removing that include should let
it still compile on any reasonable platform.

------
tzs
> The basic arithmetic operations (addition, subtraction, multiplication,
> division, square root) have a near linear running time

I thought the best known multiplication algorithms (the ones based on Fourier
transforms) for large numbers are a little slower than O(N log(N)). Has
something better been found?

~~~
dbaupp
"near linear" is sometimes used to refer to O(n log(n)^O(1)), that is, things
that are linear other than a polynomial of log(n). This includes
Schönhage–Strassen multiplication, with its O(n log(n) log(log(n)))
complexity.

------
kuwze
There is also BSDNT[0] (which is obviously BSD licensed) in case anyone is
still interested... I think this takes the cake though (as it is MIT licensed
and superior).

[0]: [https://github.com/wbhart/bsdnt](https://github.com/wbhart/bsdnt)

~~~
kuwze
I also just realized that this is only for big numbers, not arbitrary
precision.

------
slartibardfast0
MIT license makes this great for WebAssembly!

Looking forward to benchmarking this in a wasm context.

~~~
kodablah
Looking at the code this should be quite simple since libc is the only dep.
You can Emscripten at first to be easy, but to wrap it up as a JS lib, you can
probably implement the libc calls yourself easily and remove the Emscripten
dep. The author even broke off bf_realloc to put your own alloc impl (which
can be written in WASM, but I suggest writing it in C before the compilation).

~~~
slartibardfast0
cheers, sadly I won't be exploring JS lib wrapper approach.

we're already deep down the EMSCRIPTEN_BINDINGS() rabbit-hole :)

originally, the fixed size heap (/w optimisations) meant unbound use from a JS
lib was too hard to reason about; hence avoided entirely in favour of a
emscripten blackbox.

~~~
GSGSGS
Do you have a link for this ?

------
rurban
This needs some major work to be packagable into a library, esp. for non amd64
hosts. There's also no src repo, as with all his previous hacks.

Who will do the autotooling and repo hosting? I've added some sugar in my fork
on github
[https://github.com/rurban/libbf/tree/my](https://github.com/rurban/libbf/tree/my)
but I'm not sure yet if I will use it.

But the low constant overhead for small numbers, the small size, no assembler
tricks and the MIT license makes it very attractive.

~~~
rurban
I think the name is also already taken, for brainfuck and bloom filter.

------
pettou
I don't see any changelog, does anyone know what's new since the last release?

~~~
progval
According to the copyright notice, development started in 2017, so it is
possibly the first release.

------
cryptonector
This is _perfect_ for jq[0].

[0] [https://github.com/stedolan/jq](https://github.com/stedolan/jq)

~~~
jwilk
Why does jq need arbitrary precision floating-point numbers?

~~~
geofft
Because JSON's spec defines a "number" as an arbitrary-precision floating
point number, no limit on how many digits can be before or after the decimal
or on what positive or negative integers you can put after the "e". Despite
the name "JavaScript Object Notation," it does not inherit JavaScript's
traditional interpretation that a "number" is an IEEE 754 double.

(JSON also does not permit infinities or NaN, which JavaScript does permit.)

[http://json.org/](http://json.org/)

~~~
re
Wouldn't jq be better served by a library supporting arbitrary precision
decimal values? LibBF is for base-2 floating point.

~~~
whyever
Probably yes, because you always want to convert to and from base 10 strings.
mpdecimal [1] (which was developed for Python) might be a better choice,
because it uses base 10 internally.

[1] [http://www.bytereef.org/mpdecimal/](http://www.bytereef.org/mpdecimal/)

