mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
is_finite / is_nan / is_inf, frexp native.
This commit is contained in:
@@ -416,6 +416,48 @@ macro tan(x)
|
||||
$endif;
|
||||
}
|
||||
|
||||
/**
|
||||
* @require values::@is_promotable_to_float(x) `The input must be a float`
|
||||
**/
|
||||
macro bool is_finite(x)
|
||||
{
|
||||
$switch($typeof(x)):
|
||||
$case float:
|
||||
$case float16:
|
||||
return bitcast((float)x, uint) & 0x7fffffff < 0x7f800000;
|
||||
$default:
|
||||
return bitcast((double)x, ulong) & (~0u64 >> 1) < 0x7ff << 52;
|
||||
$endswitch;
|
||||
}
|
||||
|
||||
/**
|
||||
* @require values::@is_promotable_to_float(x) `The input must be a float`
|
||||
**/
|
||||
macro is_nan(x)
|
||||
{
|
||||
$switch ($typeof(x)):
|
||||
$case float:
|
||||
$case float16:
|
||||
return bitcast((float)x, uint) & 0x7fffffff > 0x7f800000;
|
||||
$default:
|
||||
return bitcast((double)x, ulong) & (~0u64 >> 1) > 0x7ff << 52;
|
||||
$endswitch;
|
||||
}
|
||||
|
||||
/**
|
||||
* @require values::@is_promotable_to_float(x) `The input must be a float`
|
||||
**/
|
||||
macro is_inf(x)
|
||||
{
|
||||
$switch ($typeof(x)):
|
||||
$case float:
|
||||
$case float16:
|
||||
return bitcast((float)x, uint) & 0x7fffffff == 0x7f800000;
|
||||
$default:
|
||||
return bitcast((double)x, ulong) & (~0u64 >> 1) == 0x7ff << 52;
|
||||
$endswitch;
|
||||
}
|
||||
|
||||
/**
|
||||
* @require values::@is_promotable_to_floatlike(x) `The input must be a number or a float vector`
|
||||
**/
|
||||
@@ -707,17 +749,6 @@ macro uint double.high_word(double d) => (uint)(bitcast(d, ulong) >> 32);
|
||||
macro uint double.low_word(double d) => (uint)bitcast(d, ulong);
|
||||
macro uint float.word(float d) => bitcast(d, uint);
|
||||
|
||||
macro is_nan(x)
|
||||
{
|
||||
$switch ($typeof(x)):
|
||||
$case float:
|
||||
return bitcast(x, uint) & 0x7fffffff > 0x7f800000;
|
||||
$case double:
|
||||
return bitcast(x, ulong) & (((ulong)-1) >> 1) > (0x7ffu64 << 52);
|
||||
$default:
|
||||
$assert(false, "Type cannot be used with is_nan");
|
||||
$endswitch;
|
||||
}
|
||||
|
||||
macro double scalbn(double x, int n) => _scalbn(x, n);
|
||||
|
||||
@@ -731,5 +762,54 @@ extern fn void _sincosf(float, float*) @extern("sincosf");
|
||||
extern fn double _tan(double x) @extern("tan");
|
||||
extern fn float _tanf(float x) @extern("tanf");
|
||||
extern fn double _scalbn(double x, int n) @extern("scalbn");
|
||||
extern fn double _frexp(double x, int* e) @extern("frexp");
|
||||
extern fn float _frexpf(float x, int* e) @extern("frexpf");
|
||||
|
||||
fn double _frexp(double x, int* e)
|
||||
{
|
||||
ulong i = bitcast(x, ulong);
|
||||
int ee = (int)((i >> 52) & 0x7ff);
|
||||
switch
|
||||
{
|
||||
case !ee:
|
||||
if (!x)
|
||||
{
|
||||
*e = 0;
|
||||
return x;
|
||||
}
|
||||
x = _frexp(x * 0x1p64, e);
|
||||
*e -= 64;
|
||||
return x;
|
||||
case ee == 0x7ff:
|
||||
return x;
|
||||
default:
|
||||
*e = ee - 0x3fe;
|
||||
i &= 0x800fffffffffffffu64;
|
||||
i |= 0x3fe0000000000000u64;
|
||||
return bitcast(i, double);
|
||||
}
|
||||
}
|
||||
|
||||
fn float _frexpf(float x, int* e)
|
||||
{
|
||||
uint i = bitcast(x, uint);
|
||||
int ee = (i >> 23) & 0xff;
|
||||
|
||||
switch
|
||||
{
|
||||
case !ee:
|
||||
if (!x)
|
||||
{
|
||||
*e = 0;
|
||||
return x;
|
||||
}
|
||||
x = _frexpf(x * 0x1p64, e);
|
||||
*e -= 64;
|
||||
return x;
|
||||
case ee == 0xff:
|
||||
return x;
|
||||
default:
|
||||
*e = ee - 0x7e;
|
||||
i &= 0x807fffffu32;
|
||||
i |= 0x3f000000u32;
|
||||
return bitcast(i, float);
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
module std::math::nolibc;
|
||||
|
||||
$if (!env::COMPILER_LIBC_AVAILABLE):
|
||||
|
||||
fn double frexp(double x, int* e) @extern("frexp") @weak
|
||||
{
|
||||
ulong i = bitcast(x, ulong);
|
||||
int ee = (int)((i >> 52) & 0x7ff);
|
||||
|
||||
if (!ee)
|
||||
{
|
||||
if (x)
|
||||
{
|
||||
x = frexp(x * 0x1p64, e);
|
||||
*e -= 64;
|
||||
}
|
||||
else
|
||||
{
|
||||
*e = 0;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
if (ee == 0x7ff) return x;
|
||||
|
||||
*e = ee - 0x3fe;
|
||||
i &= 0x800fffffffffffffu64;
|
||||
i |= 0x3fe0000000000000u64;
|
||||
return bitcast(i, double);
|
||||
}
|
||||
|
||||
fn float frexpf(float x, int* e) @extern("frexpf") @weak
|
||||
{
|
||||
uint i = bitcast(x, uint);
|
||||
int ee = (i >> 23) & 0xff;
|
||||
|
||||
if (!ee)
|
||||
{
|
||||
if (x)
|
||||
{
|
||||
x = frexpf(x * 0x1p64, e);
|
||||
*e -= 64;
|
||||
}
|
||||
else
|
||||
{
|
||||
*e = 0;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
if (ee == 0xff) return x;
|
||||
|
||||
*e = ee - 0x7e;
|
||||
i &= 0x807fffffu32;
|
||||
i |= 0x3f000000u32;
|
||||
return bitcast(i, float);
|
||||
}
|
||||
|
||||
$endif;
|
||||
Reference in New Issue
Block a user