Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add libm musl float OMs used in svcomp24 #1601

Merged
merged 10 commits into from
Jan 19, 2024
Prev Previous commit
Next Next commit
[libm] Rough approximations of expf, expm1f, logf, log1pf
  • Loading branch information
emanino authored and fbrausse committed Jan 17, 2024
commit 02472d0a35323995e65a0f541496270f7007f3d6
42 changes: 42 additions & 0 deletions src/c2goto/library/libm/expf.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#include <math.h>

float expf(float x)
{
__ESBMC_HIDE:;
/**
Highly imprecise implementation of expf(x) on floating-point operands
which satisfies the following properties:
expf(x) >= 0
expf(x) >= 1 + x
expf(-Inf) = 0
expf(0) = 1
expf(+Inf) = Inf
dexpf(x=0)/dx = 1
logf(expf(x)) = x
*/

// handle NaN inputs
if(isnan(x))
return x;

// handle infinities (x*x will overflow before x)
float xx = x * x;
if(isinf(xx)) {
if(x < 0.0f)
return 0.0f; // expf(-Inf) = 0
else
return 1.0f / 0.0f; // expf(+Inf) = Inf
}

// inverse function of the logf approximation
// i.e. inverse((x - 1) / sqrt(x))
// it is numerically unstable for x < 0
// since it relies on x - sqrt(x^2 + 4) cancelling out
return 0.5 * x * (x + sqrtf(xx + 4.0f)) + 1.0f;
}

float expm1f(float x)
{
__ESBMC_HIDE:;
return expf(x) - 1.0f;
}
33 changes: 33 additions & 0 deletions src/c2goto/library/libm/logf.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#include <math.h>

float logf(float x)
{
__ESBMC_HIDE:;
/**
Highly imprecise implementation of logf(x) on floating-point operands
which satisfies the following properties:
logf(x) <= x - 1
logf(0) = -Inf
logf(1) = 0
logf(Inf) = Inf
dlogf(x=1)/dx = 1
expf(logf(x)) = x
*/

// handle negative inputs
if(x < 0.0f)
return 0.0f / 0.0f; // return NaN

// handle positive infinity
if(isinf(x))
return x;

// ad-hoc fractional Pade' approximant
return (x - 1.0f) / sqrtf(x);
}

float log1pf(float x)
{
__ESBMC_HIDE:;
return logf(x + 1.0f);
}