GithubHelp home page GithubHelp logo

Float.toText only displays 6 fractional digits - we probably want a representation that would roundtrip as a literal. about motoko-base HOT 18 OPEN

crusso avatar crusso commented on July 30, 2024
Float.toText only displays 6 fractional digits - we probably want a representation that would roundtrip as a literal.

from motoko-base.

Comments (18)

rossberg avatar rossberg commented on July 30, 2024 1

Perhaps just extend float_fmt with a mode and a precision arg?

from motoko-base.

crusso avatar crusso commented on July 30, 2024

Using specifier "%.16g" not "%f" yields better result, but I don't know if that's good enough.

rts/float.c

export as_ptr float_fmt(double a) {
  extern int snprintf(char *__restrict, size_t, const char *__restrict, ...);
  char buf[50]; // corresponds to 150 bits of pure floatness, room for 64 bits needed
  //  const int chars = snprintf(buf, sizeof buf, "%f", a);
  const int chars = snprintf(buf, sizeof buf, "%.17g", a);
  return text_of_ptr_size(buf, chars);
}

from motoko-base.

crusso avatar crusso commented on July 30, 2024

@rossberg any advice here?

from motoko-base.

rossberg avatar rossberg commented on July 30, 2024

Yes, %.17g is enough to roundtrip, I've used that in the Wasm interpreter, and it works for all the many corner cases in the test suite that exercise bit-precise rounding behaviour (at least OCaml's implementation of the formatting, which I assume is inherited from C).

However, in practice, users may not want to see umteen zeroes all the time. We'll have to add some richer formatting functions; toText should probably default to %f.

There's also %h, of course.

from motoko-base.

ggreif avatar ggreif commented on July 30, 2024

Something like toText(f : Float, prec : ?Nat8) would be easily realisable (in the compiler, for the interpreter probably hairier).

from motoko-base.

rossberg avatar rossberg commented on July 30, 2024

@ggreif, I think it should be a separate function from toText, though. But then we'd probably want s.th like SML's realfmt type, maybe extended with a hex case for %h.

In the interpreter that ought to be trivial (using OCaml's Printf).

from motoko-base.

ggreif avatar ggreif commented on July 30, 2024

@rossberg In OCaml we can't build the format string dynamically, can we?

val fmt : string = "%.9g"
# Printf.sprintf fmt 3.14159;;
Error: This expression has type string but an expression was expected of type
         ('a -> 'b, unit, string) format =
           ('a -> 'b, unit, string, string, string, string)
           CamlinternalFormatBasics.format6

from motoko-base.

rossberg avatar rossberg commented on July 30, 2024

Following SML's basis library, here is what I propose: a function Float.toFormattedText : (Float, Format) -> Text, where the type Float.Format is defined as follows:

type Format = {
  #fix : Nat;  // like "%.*f"
  #exp : Nat;  // like "%.*e"
  #gen : Nat;  // like "%.*g"
  #hex : Nat;  // like "%.*h" a.k.a. "%.*a"
  #exact;  // like "%.17g"
}

(Making precision non-optional, since that doesn't buy you much in this form of description.)

from motoko-base.

rossberg avatar rossberg commented on July 30, 2024

@ggreif, no, but a simple switch over the 4 or 5 formats is enough. The precision can be turned into a dynamic argument by using *.

from motoko-base.

ggreif avatar ggreif commented on July 30, 2024

That's what I mean by "hairier".

from motoko-base.

rossberg avatar rossberg commented on July 30, 2024

How is that "hairy"?

from motoko-base.

ggreif avatar ggreif commented on July 30, 2024

It has more hair :-)

from motoko-base.

ggreif avatar ggreif commented on July 30, 2024

But we'll still need some supporting primitives for this to fly, right? (I'll come up with a PR in dfinity/motoko soon.)

from motoko-base.

crusso avatar crusso commented on July 30, 2024

Great, thanks guys. I'll leave that in your hands then @ggreif.

from motoko-base.

ggreif avatar ggreif commented on July 30, 2024

I totally misunderstood what "%.*f" means. I thought that the * is purely meta-notation. Another thing learned...

from motoko-base.

rossberg avatar rossberg commented on July 30, 2024

Now I see why you considered it hairy. :)

from motoko-base.

ggreif avatar ggreif commented on July 30, 2024

Now I see why you considered it hairy. :)

Precisely.

from motoko-base.

ehoogerbeets avatar ehoogerbeets commented on July 30, 2024

Is there any way we can not have toFormattedText at all and make it very very clear in the documentation that a simple toText is not for displaying to users? Formatting floating point numbers for human consumption is a locale-dependent function, as there are many different ways that different cultures format numbers with varying thousands separators, digit groupings, decimal separators, rounding rules, etc. A separate number formatter class that takes a locale would be ideal and would keep floats and natural numbers clean and small.

from motoko-base.

Related Issues (20)

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.