value · System
Float128
public value Float128 : ISignedNumber<f128>, IHashable<f128>, IComparable<f128>, IToString
- Tipo
- value
- Espacio de nombres
- System
- Ensamblado
- System.Core
- Acceso
- public, miembros de f128
- Archivo fuente
Primitives.ant
Herencia
- Interfaces
-
ISignedNumber<TSelf>IHashable<TSelf>IComparable<TSelf>IToString - Todas las interfaces
-
IComparable<TSelf>IHashable<TSelf>INumber<TSelf>ISignedNumber<TSelf>IToString
Propiedades
Métodos
ToString(str format) : str
#
As text by a format: F, N, E, P, G, R and a precision; the fixed formats show up to 33 digits.
ToString() : str
#
The shortest text that reads back as the same number.
A total order: the usual one, nan above every number and equal to itself, -0 equal to +0 (what sorting uses).
The IEEE 754 bits of the number, and back.
The number text writes (digits, a point, an exponent; nan, inf, -inf); a FormatError otherwise.
The number text writes, or null when it writes none.
Digits × 10^exponent: exact (one correctly rounded operation) up to 33 significant digits and a power of ten up to 10^48, which the type holds exactly; beyond that, within a few units in the last place.
10^power by squaring (exact up to 10^48).
Constantes
The largest finite f128, and the smallest (its negative).
The smallest f128 above zero (a subnormal).
Not a number (quiet, positive), and the infinities.
Código fuente
Float128 en Antril, descompilado a partir de su Larva HIR.
// System.Float128 — System.Core (decompiled from Larva HIR)
into namespace System
{
[Primitive("f128")]
public value Float128 : ISignedNumber<f128>, IHashable<f128>, IComparable<f128>, IToString
{
public:
/// The largest finite f128, and the smallest (its negative).
const f128 MaxValue = 1.189731495357231765085759326628007016196e4932f128;
const f128 MinValue = -1.189731495357231765085759326628007016196e4932f128;
/// The smallest f128 above zero (a subnormal).
const f128 Epsilon = 6.4751751194380251109244389582276465525e-4966f128;
/// Not a number (quiet, positive), and the infinities.
const f128 NaN = (0.0f128 / 0.0f128);
const f128 PositiveInfinity = (1.0f128 / 0.0f128);
const f128 NegativeInfinity = (-1.0f128 / 0.0f128);
[Inline]
static FromF64(f64 value) : f128 => value;
[Inline]
static ToF64(f128 value) : f64 => (f64)value;
/// As text by a format: F, N, E, P, G, R and a precision; the fixed formats show up to 33 digits.
ToString(str format) : str => NumberFormat.FormatWide(Bits(this), 128, format);
/// The shortest text that reads back as the same number.
ToString() : str => NumberFormat.FormatWide(Bits(this), 128, "G");
/// A total order: the usual one, nan above every number and equal to itself, -0 equal to +0 (what sorting uses).
CompareTo(f128 other) : i32
{
return this < other ? -1 : this > other ? 1 : this == other ? 0 : this != this ? other != other ? 0 : 1 : -1;
}
Equals(f128 other) : bool => this == other || IsNaN(this) && IsNaN(other);
Hash() : u64
{
u128 bits = Bits(this == 0.0f128 ? 0.0f128 : this);
return (u64)bits ^ (u64)(bits >> 64);
}
/// The IEEE 754 bits of the number, and back.
static unsafe Bits(f128 value) : u128
{
f128 local = value;
return *(u128*)&local;
}
static unsafe FromBits(u128 bits) : f128
{
u128 local = bits;
return *(f128*)&local;
}
static IsNaN(f128 x) : bool => x != x;
static IsInfinity(f128 x) : bool => x - x != 0.0f128 && x == x;
static IsFinite(f128 x) : bool => x - x == 0.0f128;
/// The number `text` writes (digits, a point, an exponent; `nan`, `inf`, `-inf`); a FormatError otherwise.
static Parse(str text) : f128
{
str trimmed = text.Trim();
i32 special = Float64.Special(trimmed);
if (special != 0)
return special == 1 ? (0.0f128 / 0.0f128) : special == 2 ? (1.0f128 / 0.0f128) : (-1.0f128 / 0.0f128);
if (!Float64.IsNumber(trimmed))
throw new FormatError("not a number: " + text);
return Read(trimmed.Units());
}
/// The number `text` writes, or null when it writes none.
static TryParse(str text) : f128?
{
str trimmed = text.Trim();
if (Float64.Special(trimmed) != 0)
return Parse(trimmed);
if (!Float64.IsNumber(trimmed))
return null;
return Read(trimmed.Units());
}
/// Digits × 10^exponent: exact (one correctly rounded operation) up to 33 significant digits and a power
/// of ten up to 10^48, which the type holds exactly; beyond that, within a few units in the last place.
static Read(u8[] units) : f128
{
i32 i = 0;
bool negative = units[0] == 45;
if (negative || units[0] == 43)
i++;
u128 digits = 0;
i32 count = 0;
i32 exponent = 0;
bool afterPoint = false;
loop (i < units.Length)
{
u8 c = units[i];
i++;
if (c == 46)
{
afterPoint = true;
continue;
}
if (c == 101 || c == 69)
{
bool negativeExponent = units[i] == 45;
if (negativeExponent || units[i] == 43)
i++;
i32 e = 0;
loop (i < units.Length)
{
if (e < 1000000)
e = e * 10 + ((i32)units[i] - 48);
i++;
}
exponent += negativeExponent ? -e : e;
break;
}
i32 d = (i32)c - 48;
if (digits == 0 && d == 0)
{
if (afterPoint)
exponent--;
continue;
}
if (count < 33)
{
digits = digits * 10 + (u128)d;
count++;
if (afterPoint)
exponent--;
}
else if (!afterPoint)
{
exponent++;
}
}
f128 value = (f128)digits;
loop (exponent > 0)
{
i32 step = exponent > 4000 ? 4000 : exponent;
value = value * PowerOfTen(step);
exponent -= step;
}
loop (exponent < 0)
{
i32 step = -exponent > 4000 ? 4000 : -exponent;
value = value / PowerOfTen(step);
exponent += step;
}
return negative ? -value : value;
}
/// 10^power by squaring (exact up to 10^48).
static PowerOfTen(i32 power) : f128
{
f128 result = 1.0e0f128;
f128 base = 1.0e1f128;
loop (power > 0)
{
if ((power & 1) != 0)
result = result * base;
base = base * base;
power = power >> 1;
}
return result;
}
static f128 Zero
{
get => 0.0f128;
}
static f128 One
{
get => 1.0e0f128;
}
static f128 NegativeOne
{
get => -1.0e0f128;
}
}
}