Modifiers on %a specifier? - formatting

After consulting the Format and Printf module documentation, I'm still left with an unanswered question about the %a specifier.
Starting with a very simple type:
type b = C of float
I can easily create a printing routine:
let pp ppf (C f) =
Format.fprintf ppf "%.2f" f
Such that Format.asprintf "%a" pp (C 7.6) yields "7.60".
Now, Format.asprintf "%.3a" pp (C 7.6) runs without issue, but of course I still get "7.60".
Is there a way to access the modifier within pp to determine the precision to use?

The %a specifier does not accept any flag, padding or width arguments.
Historically, the interpretation of the specifier was lax and silently ignored any such arguments
Format.printf "%0.3a"
However, enabling -strict-formats make the compiler reject this erroneous format string with
Error: invalid format "%0.3a": at character number 0, `padding' is incompatible with 'a' in sub-format "%0.3a"

The direct answer to your question, as #octachron's already covered, is essentially "no". But you can still alter the precision of your pp function by adding a precision argument to it and using the .* precision specifier instead:
let pp precision ppf (C f) =
Format.fprintf ppf "%.*f" precision f
Format.asprintf "%a" (pp 2) (C 7.6);; (* prints 7.60 *)
Format.asprintf "%a" (pp 3) (C 7.6);; (* prints 7.600 *)

Related

What are the differences between the unary minus and unary tilde minus operators in ocaml?

I'm learning OCaml, and the docs and books I'm reading aren't very clear on some things.
In simple words, what are the differences between
-10
and
~-10
To me they seem the same. I've encountered other resources trying to explain the differences, but they seem to explain in terms that I'm not yet familiar with, as the only thing I know so far are variables.
In fact, - is a binary operator, so some expression can be ambigous : f 10 -20 is treated as (f 10) - 20. For example, let's imagine this dummy function:
let f x y = (x, y)
If I want produce the tuple (10, -20) I naïvely would write something like that f 10 -20 which leads me to the following error:
# f 10 -20;;
Error: This expression has type 'a -> int * 'a
but an expression was expected of type int
because the expression is evaluated as (f 10) - 20 (so a substract over a function!!) so you can write the expression like this: f 10 (-20), which is valid or f 10 ~-20 since ~- (and ~+ and ~-. ~+. for floats) are unary operators, the predecense is properly respected.
It is easier to start by looking at how user-defined unary (~-) operators work.
type quaternion = { r:float; i:float; j:float; k:float }
let zero = { r = 0.; i = 0.; j = 0.; k = 0. }
let i = { zero with i = 1. }
let (~-) q = { r = -.q.r; i = -.q.i; j = -. q.j; k = -. q.k }
In this situation, the unary operator - (and +) is a shorthand for ~- (and ~+) when the parsing is unambiguous. For example, defining -i with
let mi = -i
works because this - could not be the binary operator -.
Nevertheless, the binary operator has a higher priority than the unary - thus
let wrong = Fun.id -i
is read as
let wrong = (Fun.id) - (i)
In this context, I can either use the full form ~-
let ok' = Fun.id ~-i
or add some parenthesis
let ok'' = Fun.id (-i)
Going back to type with literals (e.g integers, or floats), for those types, the unary + and - symbol can be part of the literal itself (e.g -10) and not an operator. For instance redefining ~- and ~+ does not change the meaning of the integer literals in
let (~+) = ()
let (~-) = ()
let really = -10
let positively_real = +10
This can be "used" to create some quite obfuscated expression:
let (~+) r = { zero with r }
let (+) x y = { r = x.r +. y.r; i = x.i +. y.i; k = x.k +. x.k; j =x.k +. y.j }
let ( *. ) s q = { r = s *. q.r; i = s *. q.i; j = s *. q.j; k = s *. q.k }
let this_is_valid x = +x + +10. *. i
OCaml has two kinds of operators - prefix and infix. The prefix operators precede expressions and infix occur in between the two expressions, e.g., in !foo we have the prefix operator ! coming before the expression foo and in 2 + 3 we have the infix operator + between expressions 2 and 3.
Operators are like normal functions except that they have a different syntax for application (aka calling), whilst functions are applied to an arbitrary number of arguments using a simple syntax of juxtaposition, e.g., f x1 x2 x3 x41, operators can have only one (prefix) or two (infix) arguments. Prefix operators are very close to normal functions, cf., f x and !x, but they have higher precedence (bind tighter) than normal function application. Contrary, the infix operators, since they are put between two expressions, enable a more natural syntax, e.g., x + y vs. (+) x y, but have lower precedence (bind less tight) than normal function application. Moreover, they enable chaining several operators in a row, e.g., x + y + z is interpreted as (x + y) + z, which is much more readable than add (add (x y) z).
Operators in OCaml distinguished purely syntactically. It means that the kind of an operator is fully defined by the first character of that operator, not by a special compiler directive, like in some other languages (i.e., there is not infix + directive in OCaml). If an operator starts with the prefix-symbol sequence, e.g., !, ?#, ~%, it is considered as prefix and if it starts with an infix-symbol then it is, correspondingly, an infix operator.
The - and -. operators are treated specially and can appear both as prefix and infix. E.g., in 1 - -2 we have - occurring both in the infix and prefix positions. However, it is only possible to disambiguate between the infix and the prefix versions of the - (and -.) operators when they occur together with other operators (infix or prefix), but when we have a general expression, the - operator is treated as infix. E.g., max 0 -1 is interpreted as (max 0) - 1 (remember that operator has lower precedence than function application, therefore when they two appear with no parentheses then functions are applied first and operators after that). Another example, Some -1, which is interpreted as Some - 1, not as Some (-1). To disambiguate such code, you can use either the parentheses, e.g., max 0 (-1), or the prefix-only versions, e.g, Some ~-1 or max 0 ~-1.
As a matter of personal style, I actually prefer parentheses as it is usually hard to keep these rules in mind when you read the code.
1) Purists will say that functions in OCaml can have only one argument and f x1 x2 x3 x4 is just ((f x1) x2) x3) x4, which would be a totally correct statement, but a little bit irrelevant to the current discussion.

How does the Prelude allow numeric literals for Nat?

In Type-Driven Development with Idris ch. 4, they say
The Prelude also defines functions and notation to allow Nat to be used like any other numeric type, so rather than writing S (S (S (S Z))), you can simply write 4.
and similarly for Fin. How does it achieve that? I've looked at the source but I can't figure it out.
from where you linked notice fromIntegerNat:
||| Convert an Integer to a Nat, mapping negative numbers to 0
fromIntegerNat : Integer -> Nat
fromIntegerNat 0 = Z
fromIntegerNat n =
if (n > 0) then
S (fromIntegerNat (assert_smaller n (n - 1)))
else
Z
and fromInteger in the Num implementation of Nat:
Num Nat where
(+) = plus
(*) = mult
fromInteger = fromIntegerNat
and Cast Integer Nat
||| Casts negative `Integers` to 0.
Cast Integer Nat where
cast = fromInteger
In the case of Idris1 it will attempt to cast from a literal (such as Char, String or Integer) into whatever type is required via those "fromFunctions" (as noted in a comment in one of the above sources: [...] '-5' desugars to 'negate (fromInteger 5)') and in general Idris1 supports implicit casting for any two types. ( http://docs.idris-lang.org/en/latest/tutorial/miscellany.html#implicit-conversions )
In the case of Idris2, there are some pragmas (%charLit fromChar, %stringLit fromString, %integerLit fromInteger) to hint the compiler to use some cast function from a literal into any other type.

i want to write a function that rewrite a float to continued fraction

i am trying to make a recursive function, that can rewrite a float to an continued fraction. I am getting an error messange that i dont understand
it seems like it can't storage certain numbers binary and how do i compare then. Thats my current theory.
condition 'cfa_reg != -1' not met
let rec float2cfrac (x : float) : int list =
if x - floor x = 0.0 then
[int x]
else
[int x] # float2cfrac (1.0/(x - floor x))
printfn "%A" (float2cfrac 3.245)// list
When I run your code. I get a stack overflow.
That means that your condition x - floor x = 0.0 is never met.
Equality with floating point numbers is a tricky thing as there is always a small precision error involved in all calculations. Never use equality, instead calculate until the difference is less than an acceptable error:
abs(x - floor x) < 0.0000000001

Objective-c power operator not clear

Im working on a small calculation app and I'm using a formula I created in PHP and now trying to translate to Objective-C however, the power operator is not clear to me.
Im looking at the following code:
float value = ((((x)*i)/12)/(1-(1+i/12)^-((x*12))))-i;
The power operator is non existent in Objective-C.
How should I apply the power operator in Objective-C and could some assist me by telling me where it should be?
(Too many parentheses! You don't need parentheses around x or (x*12), for instance.)
There is no power operator. The standard function powf() will do the job, however (pow() if you wanted a double result):
float value = x * i / 12 / (1 - powf(1 + i / 12, -12 * x)) - i;
^ is the bitwise XOR operator both in C (and so in Objective-C as well) and in PHP.
To perform a power operator use the C pow (which returns a double) or powf (which returns a float) functions
float result = powf(5, 2); // => 25
Your expression will then become (stripping away all the redundant parenthesis and leaving some for readability) :
float value = (x*i/12) / (1 - powf(1 + i/12, -x*12)) - i;

Why do some C math expressions require constants to be explicitly marked as floats?

So I just found this bug in my code and I am wondering what rules I'm not understanding.
I have a float variable logDiff, that currently contains a very small number. I want to see if it's bigger than a constant expression (80% of a 12th). I read years ago in Code Complete to just leave calculated constants in their simplest form for readability, and the compiler (XCode 4.6.3) will inline them anyway. So I have,
if ( logDiff > 1/12 * .8 ) {
I'm assuming the .8 and the fraction all evaluates to the correct number. Looks legit:
(lldb) expr (float) 1/12 * .8
(double) $1 = 0.0666666686534882
(lldb) expr logDiff
(float) $2 = 0.000328541
But it always wrongly evaluates to true. Even when I mess with enclosing parens and stuff.
(lldb) expr logDiff > 1/12 * .8
(bool) $4 = true
(lldb) expr logDiff > (1/12 * .8)
(bool) $5 = true
(lldb) expr logDiff > (float)(1/12 * .8)
(bool) $6 = true
I found I have to explicitly spell at least one of them as floats to get the correct result,
(lldb) expr logDiff > (1.f/12.f * .8f)
(bool) $7 = false
(lldb) expr logDiff > (1/12.f * .8)
(bool) $8 = false
(lldb) expr logDiff > (1./12 * .8f)
(bool) $11 = false
(lldb) expr logDiff > (1./12 * .8)
(bool) $12 = false
but I recently read a popular style guide explicitly eschew these fancier numeric literals, apparently according to my assumption that the compiler would be smarter than me and Do What I Mean.
Should I always spell my numeric constants like 1.f if they might need to be a float? Sounds superstitious. Help me understand why and when it's necessary?
The expression 1/12 is an integer division. That means that the result will be truncated as zero.
When you do (float) 1/12 you cast the one as a float, and the whole expression becomes a floating point expression.
In C int/int gives an int. If you don't explicitly tell the compiler to convert at least one to a float, it will do the division and round down to the nearest int (in this case 0).
I note that the linked style guide actually says Avoid making numbers a specific type unless necessary. In this case it is needed as what you want is for the compiler to do some type conversions
An expression such as 1 / 4 is treated as integer division and hence has no decimal precision. In this specific case, the result will be 0. You can think of this as int / int implies int.
Should I always spell my numeric constants like 1.f if they might need to be a float? Sounds superstitious. Help me understand why and when it's necessary?
It's not superstitious, you are telling the compiler that these are type literals (floats as an example) and the compiler will treat all operations on them as such.
Moreover, you could cast an expression. Consider the following:
float result = ( float ) 1 / 4;
... I am casting 1 to be a float and hence the result of float / int will be float. See datatype operation precedence (or promotion).
That is simple. Per default, a numeric value is interpredted as an int.
There are math expresssions where that does not matter too much. But in case of divisions it can drive you crazy. (int) 1 / (int) 12 is not (float) 0.08333 but (int) 0.
1/12.0 would evaluate to (float) 0.83333.
Side note: When you go for float where you used int before there is one more trap waiting for you. That is when ever you compare values for equality.
float f = 12/12.0f;
if (f = 1) ... // this may not work out. Never expect a float to be of a specific value. They can vary slightly.
Better is:
if (abs(f - 1) < 0.0001) ... // this way yoru comparison is fuzzy enough for the variances that float values may come with.