value · System
Float256
public value Float256 : ISignedNumber<f256>, IHashable<f256>, IComparable<f256>, IToString
- Kind
- value
- Namespace
- System
- Assembly
- System.Core
- Access
- public, members of f256
- Source file
Primitives.ant
Inheritance
- Interfaces
-
ISignedNumber<TSelf>IHashable<TSelf>IComparable<TSelf>IToString - All interfaces
-
IComparable<TSelf>IHashable<TSelf>INumber<TSelf>ISignedNumber<TSelf>IToString
Properties
Methods
ToString(str format) : str
#
As text by a format: F, N, E, P, G, R and a precision; the fixed formats show up to 71 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 71 significant digits and a power of ten up to 10^102, which the type holds exactly; beyond that, within a few units in the last place.
10^power by squaring (exact up to 10^102).
Constants
const f256 MaxValue = 1.61132571748576047361957211845200501064402387454966951747637125049607182699e78913f256
#
The largest finite f256, and the smallest (its negative).
const f256 Epsilon = 2.24800708647703657297018614776265182597360918266100276294348974547709294462e-78984f256
#
The smallest f256 above zero (a subnormal).
Not a number (quiet, positive), and the infinities.
Source
Float256 as Antril, decompiled from its Larva HIR.
// System.Float256 — System.Core (decompiled from Larva HIR)
into namespace System
{
[Primitive("f256")]
public value Float256 : ISignedNumber<f256>, IHashable<f256>, IComparable<f256>, IToString
{
public:
/// The largest finite f256, and the smallest (its negative).
const f256 MaxValue = 1.61132571748576047361957211845200501064402387454966951747637125049607182699e78913f256;
const f256 MinValue = -1.61132571748576047361957211845200501064402387454966951747637125049607182699e78913f256;
/// The smallest f256 above zero (a subnormal).
const f256 Epsilon = 2.24800708647703657297018614776265182597360918266100276294348974547709294462e-78984f256;
/// Not a number (quiet, positive), and the infinities.
const f256 NaN = (0.0f256 / 0.0f256);
const f256 PositiveInfinity = (1.0f256 / 0.0f256);
const f256 NegativeInfinity = (-1.0f256 / 0.0f256);
[Inline]
static FromF64(f64 value) : f256 => value;
[Inline]
static ToF64(f256 value) : f64 => (f64)value;
/// As text by a format: F, N, E, P, G, R and a precision; the fixed formats show up to 71 digits.
ToString(str format) : str => NumberFormat.FormatWide(Bits(this), 256, format);
/// The shortest text that reads back as the same number.
ToString() : str => NumberFormat.FormatWide(Bits(this), 256, "G");
/// A total order: the usual one, nan above every number and equal to itself, -0 equal to +0 (what sorting uses).
CompareTo(f256 other) : i32
{
return this < other ? -1 : this > other ? 1 : this == other ? 0 : this != this ? other != other ? 0 : 1 : -1;
}
Equals(f256 other) : bool => this == other || IsNaN(this) && IsNaN(other);
Hash() : u64
{
u256 bits = Bits(this == 0.0f256 ? 0.0f256 : this);
return (u64)bits ^ (u64)(bits >> 64) ^ (u64)(bits >> 128) ^ (u64)(bits >> 192);
}
/// The IEEE 754 bits of the number, and back.
static unsafe Bits(f256 value) : u256
{
f256 local = value;
return *(u256*)&local;
}
static unsafe FromBits(u256 bits) : f256
{
u256 local = bits;
return *(f256*)&local;
}
static IsNaN(f256 x) : bool => x != x;
static IsInfinity(f256 x) : bool => x - x != 0.0f256 && x == x;
static IsFinite(f256 x) : bool => x - x == 0.0f256;
/// The number `text` writes (digits, a point, an exponent; `nan`, `inf`, `-inf`); a FormatError otherwise.
static Parse(str text) : f256
{
str trimmed = text.Trim();
i32 special = Float64.Special(trimmed);
if (special != 0)
return special == 1 ? (0.0f256 / 0.0f256) : special == 2 ? (1.0f256 / 0.0f256) : (-1.0f256 / 0.0f256);
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) : f256?
{
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 71 significant digits and a power
/// of ten up to 10^102, which the type holds exactly; beyond that, within a few units in the last place.
static Read(u8[] units) : f256
{
i32 i = 0;
bool negative = units[0] == 45;
if (negative || units[0] == 43)
i++;
u256 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 < 71)
{
digits = digits * 10 + (u256)d;
count++;
if (afterPoint)
exponent--;
}
else if (!afterPoint)
{
exponent++;
}
}
f256 value = (f256)digits;
loop (exponent > 0)
{
i32 step = exponent > 70000 ? 70000 : exponent;
value = value * PowerOfTen(step);
exponent -= step;
}
loop (exponent < 0)
{
i32 step = -exponent > 70000 ? 70000 : -exponent;
value = value / PowerOfTen(step);
exponent += step;
}
return negative ? -value : value;
}
/// 10^power by squaring (exact up to 10^102).
static PowerOfTen(i32 power) : f256
{
f256 result = 1.0e0f256;
f256 base = 1.0e1f256;
loop (power > 0)
{
if ((power & 1) != 0)
result = result * base;
base = base * base;
power = power >> 1;
}
return result;
}
static f256 Zero
{
get => 0.0f256;
}
static f256 One
{
get => 1.0e0f256;
}
static f256 NegativeOne
{
get => -1.0e0f256;
}
}
}