Package: src/packages/reals.fdoc
Approximate Reals¶
key | file |
---|---|
real.flx | share/lib/std/scalar/real.flx |
float_format.flx | share/lib/std/scalar/float_format.flx |
//[real.flx]
instance[t in numbers] FloatAddgrp[t] {
fun zero: unit -> t = "(?1)0" ;
fun + : t * t -> t = "$1+$2" ;
fun neg : t -> t = "-$1" ;
fun - : t * t -> t = "$1-$2" ;
proc += : &t * t = "*$1+=$2;";
proc -= : &t * t = "*$1-=$2;";
}
instance[t in numbers] FloatMultSemi1[t] {
fun one: unit -> t = "(?1)1";
fun * : t * t -> t = "$1*$2";
proc *= : &t * t = "*$1*=$2;";
}
instance[t in numbers] FloatRing[t] {}
instance[t in ints \cup complexes] FloatDring[t] {
fun / : t * t -> t = "$1/$2";
fun % : t * t -> t = "$1%$2";
proc /= : &t * t = "*$1/=$2;";
proc %= : &t * t = "*$1%=$2;";
}
instance[t in floats] FloatDring[t] {
fun / : t * t -> t = "$1/$2";
fun % : t * t -> t = "fmod($1,$2)";
proc /= : &t * t = "*$1/=$2;";
proc %= : &t * t = "*$1=fmod($1,$2);";
}
instance[t in floats] Real[t] {
requires Cxx_headers::cmath;
fun abs: t -> t = "::std::abs($1)";
fun log10: t -> t = "::std::log10($1)";
fun sqrt: t -> t = "::std::sqrt($1)";
fun ceil: t -> t = "::std::ceil($1)";
fun floor: t -> t = "::std::floor($1)";
fun trunc: t -> t = "::std::trunc($1)";
fun embed: int -> t = "(?1)($1)";
fun atan2: t * t -> t = "::std::atan2($1,$2)";
}
Floating Numbers.¶
Operations on Real and Complex numbers.
//[real.flx]
// note: has to be called Fcomplex to avoid clash with class Complex
// Note: ideally we'd use constrained polymorphism for the instances..
// saves typing it all out so many times
open class Floatinf
{
const FINFINITY : float = "INFINITY" requires C99_headers::math_h;
}
open class Doubleinf
{
const DINFINITY : double = "(double)INFINITY" requires C99_headers::math_h;
}
open class Ldoubleinf
{
const LINFINITY : ldouble = "(long double)INFINITY" requires C99_headers::math_h;
}
fun isinf[T in reals] : T -> bool = "::std::isinf($1)" requires Cxx_headers::cmath;
fun isfinite[T in reals] : T -> bool = "::std::isfinite($1)" requires Cxx_headers::cmath;
fun isnan[T in reals] : T -> bool = "::std::isnan($1)" requires Cxx_headers::cmath;
ctor[T in ints] float : T = "(float)($1)";
ctor[T in ints] double : T = "(double)($1)";
ctor[T in ints] ldouble : T = "(long double)($1)";
ctor float : string = "::std::stof($1)";
ctor double : string = "::std::stod($1)";
ctor ldouble : string = "::std::stold($1)";
open Real[float];
open Real[double];
open Real[ldouble];
Real numbers¶
//[real.flx]
instance[t in reals] Tord[t] {
fun < : t * t -> bool = "$1<$2";
}
Floating Formats¶
//[float_format.flx ]
//$ Functions to format floating point numbers.
open class float_format
{
//$ Style of formatting.
//$ default (w,d) : like C "w.dG" format
//$ fixed (w,d) : like C "w.dF" format
//$ scientific (w,d) : like C "w.dE" format
variant mode =
| default of int * int
| fixed of int * int
| scientific of int * int
;
//$ Format a real number v with format m.
fun fmt[t in reals] (v:t, m: mode) =>
match m with
| default (w,p) => fmt_default(v,w,p)
| fixed (w,p) => fmt_fixed(v,w,p)
| scientific(w,p) => fmt_scientific(v,w,p)
endmatch
;
//$ Format a complex number v in x + iy form,
//$ with format m for x and y.
fun fmt[t,r with Complex[t,r]] (v:t, m: mode) =>
match m with
| default (w,p) => fmt_default(real v,w,p) +"+"+fmt_default(imag v,w,p)+"i"
| fixed (w,p) => fmt_fixed(real v,w,p)+"+"+fmt_fixed(imag v,w,p)+"i"
| scientific(w,p) => fmt_scientific(real v,w,p)+"+"+fmt_scientific(imag v,w,p)+"i"
endmatch
;
//$ Format default.
fun fmt_default[t] : t * int * int -> string="::flx::rtl::strutil::fmt_default($a)" requires package "flx_strutil";
//$ Format fixed.
fun fmt_fixed[t] : t * int * int -> string="::flx::rtl::strutil::fmt_fixed($a)" requires package "flx_strutil";
//$ Format scientfic.
fun fmt_scientific[t] : t * int * int -> string="::flx::rtl::strutil::fmt_scientific($a)" requires package "flx_strutil";
}
instance Str[float] {
fun xstr: float -> string = "::flx::rtl::strutil::str<#1>($1)" requires package "flx_strutil";
//$ Default format float, also supports nan, +inf, -inf.
noinline fun str(x:float):string =>
if isnan x then "nan"
elif isinf x then
if x > 0.0f then "+inf" else "-inf" endif
else xstr x
endif
;
}
instance Str[double] {
fun xstr: double -> string = "::flx::rtl::strutil::str<#1>($1)" requires package "flx_strutil";
//$ Default format double, also supports nan, +inf, -inf.
noinline fun str(x:double):string =>
if isnan x then "nan"
elif isinf x then
if x > 0.0 then "+inf" else "-inf" endif
else xstr x
endif
;
}
instance Str[ldouble] {
fun xstr: ldouble -> string = "::flx::rtl::strutil::str<#1>($1)" requires package "flx_strutil";
//$ Default format long double, also supports nan, +inf, -inf.
noinline fun str(x:ldouble):string =>
if isnan x then "nan"
elif isinf x then
if x > 0.0l then "+inf" else "-inf" endif
else xstr x
endif
;
}