mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-01 14:46:26 +00:00
[libc] Add implementation of few floating point manipulation functions.
Implementations of copysign[f], frexp[f], logb[f], and modf[f] are added. Reviewers: asteinhauser Differential Revision: https://reviews.llvm.org/D81134
This commit is contained in:
parent
269d843720
commit
118c13c691
@ -8,6 +8,8 @@ set(TARGET_LIBC_ENTRYPOINTS
|
||||
|
||||
set(TARGET_LIBM_ENTRYPOINTS
|
||||
# math.h entrypoints
|
||||
libc.src.math.copysign
|
||||
libc.src.math.copysignf
|
||||
libc.src.math.ceil
|
||||
libc.src.math.ceilf
|
||||
libc.src.math.cosf
|
||||
@ -17,6 +19,12 @@ set(TARGET_LIBM_ENTRYPOINTS
|
||||
libc.src.math.fabsf
|
||||
libc.src.math.floor
|
||||
libc.src.math.floorf
|
||||
libc.src.math.frexp
|
||||
libc.src.math.frexpf
|
||||
libc.src.math.logb
|
||||
libc.src.math.logbf
|
||||
libc.src.math.modf
|
||||
libc.src.math.modff
|
||||
libc.src.math.round
|
||||
libc.src.math.roundf
|
||||
libc.src.math.sincosf
|
||||
|
@ -150,6 +150,8 @@ def MathAPI : PublicAPI<"math.h"> {
|
||||
FloatT,
|
||||
];
|
||||
let Functions = [
|
||||
"copysign",
|
||||
"copysignf",
|
||||
"ceil",
|
||||
"ceilf",
|
||||
"cosf",
|
||||
@ -157,6 +159,12 @@ def MathAPI : PublicAPI<"math.h"> {
|
||||
"fabsf",
|
||||
"floor",
|
||||
"floorf",
|
||||
"frexp",
|
||||
"frexpf",
|
||||
"logb",
|
||||
"logbf",
|
||||
"modf",
|
||||
"modff",
|
||||
"expf",
|
||||
"exp2f",
|
||||
"round",
|
||||
|
@ -45,6 +45,8 @@ set(TARGET_LIBC_ENTRYPOINTS
|
||||
|
||||
set(TARGET_LIBM_ENTRYPOINTS
|
||||
# math.h entrypoints
|
||||
libc.src.math.copysign
|
||||
libc.src.math.copysignf
|
||||
libc.src.math.ceil
|
||||
libc.src.math.ceilf
|
||||
libc.src.math.cosf
|
||||
@ -54,6 +56,12 @@ set(TARGET_LIBM_ENTRYPOINTS
|
||||
libc.src.math.fabsf
|
||||
libc.src.math.floor
|
||||
libc.src.math.floorf
|
||||
libc.src.math.frexp
|
||||
libc.src.math.frexpf
|
||||
libc.src.math.logb
|
||||
libc.src.math.logbf
|
||||
libc.src.math.modf
|
||||
libc.src.math.modff
|
||||
libc.src.math.round
|
||||
libc.src.math.roundf
|
||||
libc.src.math.sincosf
|
||||
|
@ -20,6 +20,8 @@ def StdC : StandardSpec<"stdc"> {
|
||||
PtrType ThrdTTypePtr = PtrType<ThrdTType>;
|
||||
|
||||
PtrType IntPtr = PtrType<IntType>;
|
||||
PtrType FloatPtr = PtrType<FloatType>;
|
||||
PtrType DoublePtr = PtrType<DoubleType>;
|
||||
|
||||
NamedType SigHandlerT = NamedType<"__sighandler_t">;
|
||||
|
||||
@ -187,6 +189,9 @@ def StdC : StandardSpec<"stdc"> {
|
||||
],
|
||||
[], // Enumerations
|
||||
[
|
||||
FunctionSpec<"copysign", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<DoubleType>]>,
|
||||
FunctionSpec<"copysignf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<FloatType>]>,
|
||||
|
||||
FunctionSpec<"ceil", RetValSpec<DoubleType>, [ArgSpec<DoubleType>]>,
|
||||
FunctionSpec<"ceilf", RetValSpec<FloatType>, [ArgSpec<FloatType>]>,
|
||||
|
||||
@ -196,6 +201,15 @@ def StdC : StandardSpec<"stdc"> {
|
||||
FunctionSpec<"floor", RetValSpec<DoubleType>, [ArgSpec<DoubleType>]>,
|
||||
FunctionSpec<"floorf", RetValSpec<FloatType>, [ArgSpec<FloatType>]>,
|
||||
|
||||
FunctionSpec<"frexp", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<IntPtr>]>,
|
||||
FunctionSpec<"frexpf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<IntPtr>]>,
|
||||
|
||||
FunctionSpec<"logb", RetValSpec<DoubleType>, [ArgSpec<DoubleType>]>,
|
||||
FunctionSpec<"logbf", RetValSpec<FloatType>, [ArgSpec<FloatType>]>,
|
||||
|
||||
FunctionSpec<"modf", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<DoublePtr>]>,
|
||||
FunctionSpec<"modff", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<FloatPtr>]>,
|
||||
|
||||
FunctionSpec<"cosf", RetValSpec<FloatType>, [ArgSpec<FloatType>]>,
|
||||
FunctionSpec<"sinf", RetValSpec<FloatType>, [ArgSpec<FloatType>]>,
|
||||
|
||||
|
@ -189,3 +189,83 @@ add_entrypoint_object(
|
||||
.math_utils
|
||||
libc.include.math
|
||||
)
|
||||
|
||||
add_entrypoint_object(
|
||||
copysign
|
||||
SRCS
|
||||
copysign.cpp
|
||||
HDRS
|
||||
copysign.h
|
||||
DEPENDS
|
||||
libc.utils.FPUtil.fputil
|
||||
)
|
||||
|
||||
add_entrypoint_object(
|
||||
copysignf
|
||||
SRCS
|
||||
copysignf.cpp
|
||||
HDRS
|
||||
copysignf.h
|
||||
DEPENDS
|
||||
libc.utils.FPUtil.fputil
|
||||
)
|
||||
|
||||
add_entrypoint_object(
|
||||
frexp
|
||||
SRCS
|
||||
frexp.cpp
|
||||
HDRS
|
||||
frexp.h
|
||||
DEPENDS
|
||||
libc.utils.FPUtil.fputil
|
||||
)
|
||||
|
||||
add_entrypoint_object(
|
||||
frexpf
|
||||
SRCS
|
||||
frexpf.cpp
|
||||
HDRS
|
||||
frexpf.h
|
||||
DEPENDS
|
||||
libc.utils.FPUtil.fputil
|
||||
)
|
||||
|
||||
add_entrypoint_object(
|
||||
logb
|
||||
SRCS
|
||||
logb.cpp
|
||||
HDRS
|
||||
logb.h
|
||||
DEPENDS
|
||||
libc.utils.FPUtil.fputil
|
||||
)
|
||||
|
||||
add_entrypoint_object(
|
||||
logbf
|
||||
SRCS
|
||||
logbf.cpp
|
||||
HDRS
|
||||
logbf.h
|
||||
DEPENDS
|
||||
libc.utils.FPUtil.fputil
|
||||
)
|
||||
|
||||
add_entrypoint_object(
|
||||
modf
|
||||
SRCS
|
||||
modf.cpp
|
||||
HDRS
|
||||
modf.h
|
||||
DEPENDS
|
||||
libc.utils.FPUtil.fputil
|
||||
)
|
||||
|
||||
add_entrypoint_object(
|
||||
modff
|
||||
SRCS
|
||||
modff.cpp
|
||||
HDRS
|
||||
modff.h
|
||||
DEPENDS
|
||||
libc.utils.FPUtil.fputil
|
||||
)
|
||||
|
18
libc/src/math/copysign.cpp
Normal file
18
libc/src/math/copysign.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
//===-- Implementation of copysign function -------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "src/__support/common.h"
|
||||
#include "utils/FPUtil/ManipulationFunctions.h"
|
||||
|
||||
namespace __llvm_libc {
|
||||
|
||||
double LLVM_LIBC_ENTRYPOINT(copysign)(double x, double y) {
|
||||
return fputil::copysign(x, y);
|
||||
}
|
||||
|
||||
} // namespace __llvm_libc
|
18
libc/src/math/copysign.h
Normal file
18
libc/src/math/copysign.h
Normal file
@ -0,0 +1,18 @@
|
||||
//===-- Implementation header for copysign ----------------------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIBC_SRC_MATH_COPYSIGN_H
|
||||
#define LLVM_LIBC_SRC_MATH_COPYSIGN_H
|
||||
|
||||
namespace __llvm_libc {
|
||||
|
||||
double copysign(double x, double y);
|
||||
|
||||
} // namespace __llvm_libc
|
||||
|
||||
#endif // LLVM_LIBC_SRC_MATH_COPYSIGN_H
|
18
libc/src/math/copysignf.cpp
Normal file
18
libc/src/math/copysignf.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
//===-- Implementation of copysignf function ------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "src/__support/common.h"
|
||||
#include "utils/FPUtil/ManipulationFunctions.h"
|
||||
|
||||
namespace __llvm_libc {
|
||||
|
||||
float LLVM_LIBC_ENTRYPOINT(copysignf)(float x, float y) {
|
||||
return fputil::copysign(x, y);
|
||||
}
|
||||
|
||||
} // namespace __llvm_libc
|
18
libc/src/math/copysignf.h
Normal file
18
libc/src/math/copysignf.h
Normal file
@ -0,0 +1,18 @@
|
||||
//===-- Implementation header for copysignf ---------------------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIBC_SRC_MATH_COPYSIGNF_H
|
||||
#define LLVM_LIBC_SRC_MATH_COPYSIGNF_H
|
||||
|
||||
namespace __llvm_libc {
|
||||
|
||||
float copysignf(float x, float y);
|
||||
|
||||
} // namespace __llvm_libc
|
||||
|
||||
#endif // LLVM_LIBC_SRC_MATH_COPYSIGNF_H
|
18
libc/src/math/frexp.cpp
Normal file
18
libc/src/math/frexp.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
//===-- Implementation of frexp function ----------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "src/__support/common.h"
|
||||
#include "utils/FPUtil/ManipulationFunctions.h"
|
||||
|
||||
namespace __llvm_libc {
|
||||
|
||||
double LLVM_LIBC_ENTRYPOINT(frexp)(double x, int *exp) {
|
||||
return fputil::frexp(x, *exp);
|
||||
}
|
||||
|
||||
} // namespace __llvm_libc
|
18
libc/src/math/frexp.h
Normal file
18
libc/src/math/frexp.h
Normal file
@ -0,0 +1,18 @@
|
||||
//===-- Implementation header for frexp -------------------------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIBC_SRC_MATH_FREXP_H
|
||||
#define LLVM_LIBC_SRC_MATH_FREXP_H
|
||||
|
||||
namespace __llvm_libc {
|
||||
|
||||
double frexp(double x, int *exp);
|
||||
|
||||
} // namespace __llvm_libc
|
||||
|
||||
#endif // LLVM_LIBC_SRC_MATH_FREXP_H
|
18
libc/src/math/frexpf.cpp
Normal file
18
libc/src/math/frexpf.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
//===-- Implementation of frexpf function ---------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "src/__support/common.h"
|
||||
#include "utils/FPUtil/ManipulationFunctions.h"
|
||||
|
||||
namespace __llvm_libc {
|
||||
|
||||
float LLVM_LIBC_ENTRYPOINT(frexpf)(float x, int *exp) {
|
||||
return fputil::frexp(x, *exp);
|
||||
}
|
||||
|
||||
} // namespace __llvm_libc
|
18
libc/src/math/frexpf.h
Normal file
18
libc/src/math/frexpf.h
Normal file
@ -0,0 +1,18 @@
|
||||
//===-- Implementation header for frexpf ------------------------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIBC_SRC_MATH_FREXPF_H
|
||||
#define LLVM_LIBC_SRC_MATH_FREXPF_H
|
||||
|
||||
namespace __llvm_libc {
|
||||
|
||||
float frexpf(float x, int *exp);
|
||||
|
||||
} // namespace __llvm_libc
|
||||
|
||||
#endif // LLVM_LIBC_SRC_MATH_FREXPF_H
|
16
libc/src/math/logb.cpp
Normal file
16
libc/src/math/logb.cpp
Normal file
@ -0,0 +1,16 @@
|
||||
//===-- Implementation of logb function -----------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "src/__support/common.h"
|
||||
#include "utils/FPUtil/ManipulationFunctions.h"
|
||||
|
||||
namespace __llvm_libc {
|
||||
|
||||
double LLVM_LIBC_ENTRYPOINT(logb)(double x) { return fputil::logb(x); }
|
||||
|
||||
} // namespace __llvm_libc
|
18
libc/src/math/logb.h
Normal file
18
libc/src/math/logb.h
Normal file
@ -0,0 +1,18 @@
|
||||
//===-- Implementation header for logb --------------------------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIBC_SRC_MATH_LOGB_H
|
||||
#define LLVM_LIBC_SRC_MATH_LOGB_H
|
||||
|
||||
namespace __llvm_libc {
|
||||
|
||||
double logb(double x);
|
||||
|
||||
} // namespace __llvm_libc
|
||||
|
||||
#endif // LLVM_LIBC_SRC_MATH_LOGB_H
|
16
libc/src/math/logbf.cpp
Normal file
16
libc/src/math/logbf.cpp
Normal file
@ -0,0 +1,16 @@
|
||||
//===-- Implementation of logbf function ---------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "src/__support/common.h"
|
||||
#include "utils/FPUtil/ManipulationFunctions.h"
|
||||
|
||||
namespace __llvm_libc {
|
||||
|
||||
float LLVM_LIBC_ENTRYPOINT(logbf)(float x) { return fputil::logb(x); }
|
||||
|
||||
} // namespace __llvm_libc
|
18
libc/src/math/logbf.h
Normal file
18
libc/src/math/logbf.h
Normal file
@ -0,0 +1,18 @@
|
||||
//===-- Implementation header for logbf -------------------------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIBC_SRC_MATH_LOGBF_H
|
||||
#define LLVM_LIBC_SRC_MATH_LOGBF_H
|
||||
|
||||
namespace __llvm_libc {
|
||||
|
||||
float logbf(float x);
|
||||
|
||||
} // namespace __llvm_libc
|
||||
|
||||
#endif // LLVM_LIBC_SRC_MATH_LOGBF_H
|
18
libc/src/math/modf.cpp
Normal file
18
libc/src/math/modf.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
//===-- Implementation of modf function -----------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "src/__support/common.h"
|
||||
#include "utils/FPUtil/ManipulationFunctions.h"
|
||||
|
||||
namespace __llvm_libc {
|
||||
|
||||
double LLVM_LIBC_ENTRYPOINT(modf)(double x, double *iptr) {
|
||||
return fputil::modf(x, *iptr);
|
||||
}
|
||||
|
||||
} // namespace __llvm_libc
|
18
libc/src/math/modf.h
Normal file
18
libc/src/math/modf.h
Normal file
@ -0,0 +1,18 @@
|
||||
//===-- Implementation header for modf --------------------------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIBC_SRC_MATH_MODF_H
|
||||
#define LLVM_LIBC_SRC_MATH_MODF_H
|
||||
|
||||
namespace __llvm_libc {
|
||||
|
||||
double modf(double x, double *iptr);
|
||||
|
||||
} // namespace __llvm_libc
|
||||
|
||||
#endif // LLVM_LIBC_SRC_MATH_MODF_H
|
18
libc/src/math/modff.cpp
Normal file
18
libc/src/math/modff.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
//===-- Implementation of modf function -----------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "src/__support/common.h"
|
||||
#include "utils/FPUtil/ManipulationFunctions.h"
|
||||
|
||||
namespace __llvm_libc {
|
||||
|
||||
float LLVM_LIBC_ENTRYPOINT(modff)(float x, float *iptr) {
|
||||
return fputil::modf(x, *iptr);
|
||||
}
|
||||
|
||||
} // namespace __llvm_libc
|
18
libc/src/math/modff.h
Normal file
18
libc/src/math/modff.h
Normal file
@ -0,0 +1,18 @@
|
||||
//===-- Implementation header for modff -------------------------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIBC_SRC_MATH_MODFF_H
|
||||
#define LLVM_LIBC_SRC_MATH_MODFF_H
|
||||
|
||||
namespace __llvm_libc {
|
||||
|
||||
float modff(float x, float *iptr);
|
||||
|
||||
} // namespace __llvm_libc
|
||||
|
||||
#endif // LLVM_LIBC_SRC_MATH_MODFF_H
|
@ -228,3 +228,99 @@ add_math_unittest(
|
||||
libc.src.math.exp2f
|
||||
libc.utils.FPUtil.fputil
|
||||
)
|
||||
|
||||
add_math_unittest(
|
||||
copysign_test
|
||||
SUITE
|
||||
libc_math_unittests
|
||||
SRCS
|
||||
copysign_test.cpp
|
||||
DEPENDS
|
||||
libc.include.math
|
||||
libc.src.math.copysign
|
||||
libc.utils.FPUtil.fputil
|
||||
)
|
||||
|
||||
add_math_unittest(
|
||||
copysignf_test
|
||||
SUITE
|
||||
libc_math_unittests
|
||||
SRCS
|
||||
copysignf_test.cpp
|
||||
DEPENDS
|
||||
libc.include.math
|
||||
libc.src.math.copysignf
|
||||
libc.utils.FPUtil.fputil
|
||||
)
|
||||
|
||||
add_math_unittest(
|
||||
frexp_test
|
||||
SUITE
|
||||
libc_math_unittests
|
||||
SRCS
|
||||
frexp_test.cpp
|
||||
DEPENDS
|
||||
libc.include.math
|
||||
libc.src.math.frexp
|
||||
libc.utils.FPUtil.fputil
|
||||
)
|
||||
|
||||
add_math_unittest(
|
||||
frexpf_test
|
||||
SUITE
|
||||
libc_math_unittests
|
||||
SRCS
|
||||
frexpf_test.cpp
|
||||
DEPENDS
|
||||
libc.include.math
|
||||
libc.src.math.frexpf
|
||||
libc.utils.FPUtil.fputil
|
||||
)
|
||||
|
||||
add_math_unittest(
|
||||
logb_test
|
||||
SUITE
|
||||
libc_math_unittests
|
||||
SRCS
|
||||
logb_test.cpp
|
||||
DEPENDS
|
||||
libc.include.math
|
||||
libc.src.math.logb
|
||||
libc.utils.FPUtil.fputil
|
||||
)
|
||||
|
||||
add_math_unittest(
|
||||
logbf_test
|
||||
SUITE
|
||||
libc_math_unittests
|
||||
SRCS
|
||||
logbf_test.cpp
|
||||
DEPENDS
|
||||
libc.include.math
|
||||
libc.src.math.logbf
|
||||
libc.utils.FPUtil.fputil
|
||||
)
|
||||
|
||||
add_math_unittest(
|
||||
modf_test
|
||||
SUITE
|
||||
libc_math_unittests
|
||||
SRCS
|
||||
modf_test.cpp
|
||||
DEPENDS
|
||||
libc.include.math
|
||||
libc.src.math.modf
|
||||
libc.utils.FPUtil.fputil
|
||||
)
|
||||
|
||||
add_math_unittest(
|
||||
modff_test
|
||||
SUITE
|
||||
libc_math_unittests
|
||||
SRCS
|
||||
modff_test.cpp
|
||||
DEPENDS
|
||||
libc.include.math
|
||||
libc.src.math.modff
|
||||
libc.utils.FPUtil.fputil
|
||||
)
|
||||
|
63
libc/test/src/math/copysign_test.cpp
Normal file
63
libc/test/src/math/copysign_test.cpp
Normal file
@ -0,0 +1,63 @@
|
||||
//===-- Unittests for copysign --------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "include/math.h"
|
||||
#include "src/math/copysign.h"
|
||||
#include "utils/FPUtil/BitPatterns.h"
|
||||
#include "utils/FPUtil/FloatOperations.h"
|
||||
#include "utils/FPUtil/FloatProperties.h"
|
||||
#include "utils/UnitTest/Test.h"
|
||||
|
||||
using __llvm_libc::fputil::valueAsBits;
|
||||
using __llvm_libc::fputil::valueFromBits;
|
||||
|
||||
using BitPatterns = __llvm_libc::fputil::BitPatterns<double>;
|
||||
using Properties = __llvm_libc::fputil::FloatProperties<double>;
|
||||
|
||||
TEST(CopySignTest, SpecialNumbers) {
|
||||
EXPECT_EQ(BitPatterns::aNegativeQuietNaN,
|
||||
valueAsBits(__llvm_libc::copysign(
|
||||
valueFromBits(BitPatterns::aQuietNaN), -1.0)));
|
||||
EXPECT_EQ(BitPatterns::aQuietNaN,
|
||||
valueAsBits(__llvm_libc::copysign(
|
||||
valueFromBits(BitPatterns::aNegativeQuietNaN), 1.0)));
|
||||
|
||||
EXPECT_EQ(BitPatterns::aNegativeSignallingNaN,
|
||||
valueAsBits(__llvm_libc::copysign(
|
||||
valueFromBits(BitPatterns::aSignallingNaN), -1.0)));
|
||||
EXPECT_EQ(BitPatterns::aSignallingNaN,
|
||||
valueAsBits(__llvm_libc::copysign(
|
||||
valueFromBits(BitPatterns::aNegativeSignallingNaN), 1.0)));
|
||||
|
||||
EXPECT_EQ(BitPatterns::negInf, valueAsBits(__llvm_libc::copysign(
|
||||
valueFromBits(BitPatterns::inf), -1.0)));
|
||||
EXPECT_EQ(BitPatterns::inf, valueAsBits(__llvm_libc::copysign(
|
||||
valueFromBits(BitPatterns::negInf), 1.0)));
|
||||
|
||||
EXPECT_EQ(BitPatterns::negZero, valueAsBits(__llvm_libc::copysign(
|
||||
valueFromBits(BitPatterns::zero), -1.0)));
|
||||
EXPECT_EQ(BitPatterns::zero, valueAsBits(__llvm_libc::copysign(
|
||||
valueFromBits(BitPatterns::negZero), 1.0)));
|
||||
}
|
||||
|
||||
TEST(CopySignTest, InDoubleRange) {
|
||||
using BitsType = Properties::BitsType;
|
||||
constexpr BitsType count = 1000000;
|
||||
constexpr BitsType step = UINT64_MAX / count;
|
||||
for (BitsType i = 0, v = 0; i <= count; ++i, v += step) {
|
||||
double x = valueFromBits(v);
|
||||
if (isnan(x) || isinf(x) || x == 0)
|
||||
continue;
|
||||
|
||||
double res1 = __llvm_libc::copysign(x, -x);
|
||||
ASSERT_TRUE(res1 == -x);
|
||||
|
||||
double res2 = __llvm_libc::copysign(x, x);
|
||||
ASSERT_TRUE(res2 == x);
|
||||
}
|
||||
}
|
65
libc/test/src/math/copysignf_test.cpp
Normal file
65
libc/test/src/math/copysignf_test.cpp
Normal file
@ -0,0 +1,65 @@
|
||||
//===-- Unittests for copysignf
|
||||
//--------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "include/math.h"
|
||||
#include "src/math/copysignf.h"
|
||||
#include "utils/FPUtil/BitPatterns.h"
|
||||
#include "utils/FPUtil/FloatOperations.h"
|
||||
#include "utils/FPUtil/FloatProperties.h"
|
||||
#include "utils/UnitTest/Test.h"
|
||||
|
||||
using __llvm_libc::fputil::valueAsBits;
|
||||
using __llvm_libc::fputil::valueFromBits;
|
||||
|
||||
using BitPatterns = __llvm_libc::fputil::BitPatterns<float>;
|
||||
using Properties = __llvm_libc::fputil::FloatProperties<float>;
|
||||
|
||||
TEST(CopySignFTest, SpecialNumbers) {
|
||||
EXPECT_EQ(BitPatterns::aNegativeQuietNaN,
|
||||
valueAsBits(__llvm_libc::copysignf(
|
||||
valueFromBits(BitPatterns::aQuietNaN), -1.0f)));
|
||||
EXPECT_EQ(BitPatterns::aQuietNaN,
|
||||
valueAsBits(__llvm_libc::copysignf(
|
||||
valueFromBits(BitPatterns::aNegativeQuietNaN), 1.0f)));
|
||||
|
||||
EXPECT_EQ(BitPatterns::aNegativeSignallingNaN,
|
||||
valueAsBits(__llvm_libc::copysignf(
|
||||
valueFromBits(BitPatterns::aSignallingNaN), -1.0f)));
|
||||
EXPECT_EQ(BitPatterns::aSignallingNaN,
|
||||
valueAsBits(__llvm_libc::copysignf(
|
||||
valueFromBits(BitPatterns::aNegativeSignallingNaN), 1.0f)));
|
||||
|
||||
EXPECT_EQ(BitPatterns::negInf, valueAsBits(__llvm_libc::copysignf(
|
||||
valueFromBits(BitPatterns::inf), -1.0f)));
|
||||
EXPECT_EQ(BitPatterns::inf, valueAsBits(__llvm_libc::copysignf(
|
||||
valueFromBits(BitPatterns::negInf), 1.0f)));
|
||||
|
||||
EXPECT_EQ(BitPatterns::negZero,
|
||||
valueAsBits(__llvm_libc::copysignf(valueFromBits(BitPatterns::zero),
|
||||
-1.0f)));
|
||||
EXPECT_EQ(BitPatterns::zero, valueAsBits(__llvm_libc::copysignf(
|
||||
valueFromBits(BitPatterns::negZero), 1.0f)));
|
||||
}
|
||||
|
||||
TEST(CopySignFTest, InDoubleRange) {
|
||||
using BitsType = Properties::BitsType;
|
||||
constexpr BitsType count = 1000000;
|
||||
constexpr BitsType step = UINT32_MAX / count;
|
||||
for (BitsType i = 0, v = 0; i <= count; ++i, v += step) {
|
||||
float x = valueFromBits(v);
|
||||
if (isnan(x) || isinf(x) || x == 0)
|
||||
continue;
|
||||
|
||||
float res1 = __llvm_libc::copysignf(x, -x);
|
||||
ASSERT_TRUE(res1 == -x);
|
||||
|
||||
float res2 = __llvm_libc::copysignf(x, x);
|
||||
ASSERT_TRUE(res2 == x);
|
||||
}
|
||||
}
|
141
libc/test/src/math/frexp_test.cpp
Normal file
141
libc/test/src/math/frexp_test.cpp
Normal file
@ -0,0 +1,141 @@
|
||||
//===-- Unittests for frexp -----------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "include/math.h"
|
||||
#include "src/math/frexp.h"
|
||||
#include "utils/FPUtil/BitPatterns.h"
|
||||
#include "utils/FPUtil/FloatOperations.h"
|
||||
#include "utils/FPUtil/FloatProperties.h"
|
||||
#include "utils/UnitTest/Test.h"
|
||||
|
||||
using __llvm_libc::fputil::valueAsBits;
|
||||
using __llvm_libc::fputil::valueFromBits;
|
||||
|
||||
using BitPatterns = __llvm_libc::fputil::BitPatterns<double>;
|
||||
using Properties = __llvm_libc::fputil::FloatProperties<double>;
|
||||
|
||||
TEST(FrexpTest, SpecialNumbers) {
|
||||
int exponent;
|
||||
|
||||
EXPECT_EQ(BitPatterns::aQuietNaN,
|
||||
valueAsBits(__llvm_libc::frexp(
|
||||
valueFromBits(BitPatterns::aQuietNaN), &exponent)));
|
||||
EXPECT_EQ(BitPatterns::aNegativeQuietNaN,
|
||||
valueAsBits(__llvm_libc::frexp(
|
||||
valueFromBits(BitPatterns::aNegativeQuietNaN), &exponent)));
|
||||
|
||||
EXPECT_EQ(BitPatterns::aSignallingNaN,
|
||||
valueAsBits(__llvm_libc::frexp(
|
||||
valueFromBits(BitPatterns::aSignallingNaN), &exponent)));
|
||||
EXPECT_EQ(
|
||||
BitPatterns::aNegativeSignallingNaN,
|
||||
valueAsBits(__llvm_libc::frexp(
|
||||
valueFromBits(BitPatterns::aNegativeSignallingNaN), &exponent)));
|
||||
|
||||
EXPECT_EQ(BitPatterns::inf, valueAsBits(__llvm_libc::frexp(
|
||||
valueFromBits(BitPatterns::inf), &exponent)));
|
||||
EXPECT_EQ(BitPatterns::negInf,
|
||||
valueAsBits(__llvm_libc::frexp(valueFromBits(BitPatterns::negInf),
|
||||
&exponent)));
|
||||
|
||||
EXPECT_EQ(BitPatterns::zero,
|
||||
valueAsBits(__llvm_libc::frexp(valueFromBits(BitPatterns::zero),
|
||||
&exponent)));
|
||||
EXPECT_EQ(exponent, 0);
|
||||
EXPECT_EQ(BitPatterns::negZero,
|
||||
valueAsBits(__llvm_libc::frexp(valueFromBits(BitPatterns::negZero),
|
||||
&exponent)));
|
||||
EXPECT_EQ(exponent, 0);
|
||||
}
|
||||
|
||||
TEST(FrexpTest, PowersOfTwo) {
|
||||
int exponent;
|
||||
|
||||
EXPECT_EQ(valueAsBits(0.5), valueAsBits(__llvm_libc::frexp(1.0, &exponent)));
|
||||
EXPECT_EQ(exponent, 1);
|
||||
EXPECT_EQ(valueAsBits(-0.5),
|
||||
valueAsBits(__llvm_libc::frexp(-1.0, &exponent)));
|
||||
EXPECT_EQ(exponent, 1);
|
||||
|
||||
EXPECT_EQ(valueAsBits(0.5), valueAsBits(__llvm_libc::frexp(2.0, &exponent)));
|
||||
EXPECT_EQ(exponent, 2);
|
||||
EXPECT_EQ(valueAsBits(-0.5),
|
||||
valueAsBits(__llvm_libc::frexp(-2.0, &exponent)));
|
||||
EXPECT_EQ(exponent, 2);
|
||||
|
||||
EXPECT_EQ(valueAsBits(0.5), valueAsBits(__llvm_libc::frexp(4.0, &exponent)));
|
||||
EXPECT_EQ(exponent, 3);
|
||||
EXPECT_EQ(valueAsBits(-0.5),
|
||||
valueAsBits(__llvm_libc::frexp(-4.0, &exponent)));
|
||||
EXPECT_EQ(exponent, 3);
|
||||
|
||||
EXPECT_EQ(valueAsBits(0.5), valueAsBits(__llvm_libc::frexp(8.0, &exponent)));
|
||||
EXPECT_EQ(exponent, 4);
|
||||
EXPECT_EQ(valueAsBits(-0.5),
|
||||
valueAsBits(__llvm_libc::frexp(-8.0, &exponent)));
|
||||
EXPECT_EQ(exponent, 4);
|
||||
|
||||
EXPECT_EQ(valueAsBits(0.5), valueAsBits(__llvm_libc::frexp(16.0, &exponent)));
|
||||
EXPECT_EQ(exponent, 5);
|
||||
EXPECT_EQ(valueAsBits(-0.5),
|
||||
valueAsBits(__llvm_libc::frexp(-16.0, &exponent)));
|
||||
EXPECT_EQ(exponent, 5);
|
||||
|
||||
EXPECT_EQ(valueAsBits(0.5), valueAsBits(__llvm_libc::frexp(32.0, &exponent)));
|
||||
EXPECT_EQ(exponent, 6);
|
||||
EXPECT_EQ(valueAsBits(-0.5),
|
||||
valueAsBits(__llvm_libc::frexp(-32.0, &exponent)));
|
||||
EXPECT_EQ(exponent, 6);
|
||||
|
||||
EXPECT_EQ(valueAsBits(0.5), valueAsBits(__llvm_libc::frexp(64.0, &exponent)));
|
||||
EXPECT_EQ(exponent, 7);
|
||||
EXPECT_EQ(valueAsBits(-0.5),
|
||||
valueAsBits(__llvm_libc::frexp(-64.0, &exponent)));
|
||||
EXPECT_EQ(exponent, 7);
|
||||
}
|
||||
|
||||
TEST(FrexpTest, SomeIntegers) {
|
||||
int exponent;
|
||||
|
||||
EXPECT_EQ(valueAsBits(0.75),
|
||||
valueAsBits(__llvm_libc::frexp(24.0, &exponent)));
|
||||
EXPECT_EQ(exponent, 5);
|
||||
EXPECT_EQ(valueAsBits(-0.75),
|
||||
valueAsBits(__llvm_libc::frexp(-24.0, &exponent)));
|
||||
EXPECT_EQ(exponent, 5);
|
||||
|
||||
EXPECT_EQ(valueAsBits(0.625),
|
||||
valueAsBits(__llvm_libc::frexp(40.0, &exponent)));
|
||||
EXPECT_EQ(exponent, 6);
|
||||
EXPECT_EQ(valueAsBits(-0.625),
|
||||
valueAsBits(__llvm_libc::frexp(-40.0, &exponent)));
|
||||
EXPECT_EQ(exponent, 6);
|
||||
|
||||
EXPECT_EQ(valueAsBits(0.78125),
|
||||
valueAsBits(__llvm_libc::frexp(800.0, &exponent)));
|
||||
EXPECT_EQ(exponent, 10);
|
||||
EXPECT_EQ(valueAsBits(-0.78125),
|
||||
valueAsBits(__llvm_libc::frexp(-800.0, &exponent)));
|
||||
EXPECT_EQ(exponent, 10);
|
||||
}
|
||||
|
||||
TEST(FrexpTest, InDoubleRange) {
|
||||
using BitsType = Properties::BitsType;
|
||||
constexpr BitsType count = 1000000;
|
||||
constexpr BitsType step = UINT64_MAX / count;
|
||||
for (BitsType i = 0, v = 0; i <= count; ++i, v += step) {
|
||||
double x = valueFromBits(v);
|
||||
if (isnan(x) || isinf(x) || x == 0.0)
|
||||
continue;
|
||||
int exponent;
|
||||
double frac = __llvm_libc::frexp(x, &exponent);
|
||||
|
||||
ASSERT_TRUE(__llvm_libc::fputil::abs(frac) < 1.0);
|
||||
ASSERT_TRUE(__llvm_libc::fputil::abs(frac) >= 0.5);
|
||||
}
|
||||
}
|
150
libc/test/src/math/frexpf_test.cpp
Normal file
150
libc/test/src/math/frexpf_test.cpp
Normal file
@ -0,0 +1,150 @@
|
||||
//===-- Unittests for frexpf
|
||||
//-----------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "include/math.h"
|
||||
#include "src/math/frexpf.h"
|
||||
#include "utils/FPUtil/BitPatterns.h"
|
||||
#include "utils/FPUtil/FloatOperations.h"
|
||||
#include "utils/FPUtil/FloatProperties.h"
|
||||
#include "utils/MPFRWrapper/MPFRUtils.h"
|
||||
#include "utils/UnitTest/Test.h"
|
||||
|
||||
using __llvm_libc::fputil::valueAsBits;
|
||||
using __llvm_libc::fputil::valueFromBits;
|
||||
|
||||
using BitPatterns = __llvm_libc::fputil::BitPatterns<float>;
|
||||
using Properties = __llvm_libc::fputil::FloatProperties<float>;
|
||||
|
||||
TEST(FrexpfTest, SpecialNumbers) {
|
||||
int exponent;
|
||||
|
||||
EXPECT_EQ(BitPatterns::aQuietNaN,
|
||||
valueAsBits(__llvm_libc::frexpf(
|
||||
valueFromBits(BitPatterns::aQuietNaN), &exponent)));
|
||||
EXPECT_EQ(BitPatterns::aNegativeQuietNaN,
|
||||
valueAsBits(__llvm_libc::frexpf(
|
||||
valueFromBits(BitPatterns::aNegativeQuietNaN), &exponent)));
|
||||
|
||||
EXPECT_EQ(BitPatterns::aSignallingNaN,
|
||||
valueAsBits(__llvm_libc::frexpf(
|
||||
valueFromBits(BitPatterns::aSignallingNaN), &exponent)));
|
||||
EXPECT_EQ(
|
||||
BitPatterns::aNegativeSignallingNaN,
|
||||
valueAsBits(__llvm_libc::frexpf(
|
||||
valueFromBits(BitPatterns::aNegativeSignallingNaN), &exponent)));
|
||||
|
||||
EXPECT_EQ(BitPatterns::inf, valueAsBits(__llvm_libc::frexpf(
|
||||
valueFromBits(BitPatterns::inf), &exponent)));
|
||||
EXPECT_EQ(BitPatterns::negInf,
|
||||
valueAsBits(__llvm_libc::frexpf(valueFromBits(BitPatterns::negInf),
|
||||
&exponent)));
|
||||
|
||||
EXPECT_EQ(BitPatterns::zero,
|
||||
valueAsBits(__llvm_libc::frexpf(valueFromBits(BitPatterns::zero),
|
||||
&exponent)));
|
||||
EXPECT_EQ(exponent, 0);
|
||||
EXPECT_EQ(BitPatterns::negZero,
|
||||
valueAsBits(__llvm_libc::frexpf(valueFromBits(BitPatterns::negZero),
|
||||
&exponent)));
|
||||
EXPECT_EQ(exponent, 0);
|
||||
}
|
||||
|
||||
TEST(FrexpfTest, PowersOfTwo) {
|
||||
int exponent;
|
||||
|
||||
EXPECT_EQ(valueAsBits(0.5f),
|
||||
valueAsBits(__llvm_libc::frexpf(1.0f, &exponent)));
|
||||
EXPECT_EQ(exponent, 1);
|
||||
EXPECT_EQ(valueAsBits(-0.5f),
|
||||
valueAsBits(__llvm_libc::frexpf(-1.0f, &exponent)));
|
||||
EXPECT_EQ(exponent, 1);
|
||||
|
||||
EXPECT_EQ(valueAsBits(0.5f),
|
||||
valueAsBits(__llvm_libc::frexpf(2.0f, &exponent)));
|
||||
EXPECT_EQ(exponent, 2);
|
||||
EXPECT_EQ(valueAsBits(-0.5f),
|
||||
valueAsBits(__llvm_libc::frexpf(-2.0f, &exponent)));
|
||||
EXPECT_EQ(exponent, 2);
|
||||
|
||||
EXPECT_EQ(valueAsBits(0.5f),
|
||||
valueAsBits(__llvm_libc::frexpf(4.0f, &exponent)));
|
||||
EXPECT_EQ(exponent, 3);
|
||||
EXPECT_EQ(valueAsBits(-0.5f),
|
||||
valueAsBits(__llvm_libc::frexpf(-4.0f, &exponent)));
|
||||
EXPECT_EQ(exponent, 3);
|
||||
|
||||
EXPECT_EQ(valueAsBits(0.5f),
|
||||
valueAsBits(__llvm_libc::frexpf(8.0f, &exponent)));
|
||||
EXPECT_EQ(exponent, 4);
|
||||
EXPECT_EQ(valueAsBits(-0.5f),
|
||||
valueAsBits(__llvm_libc::frexpf(-8.0f, &exponent)));
|
||||
EXPECT_EQ(exponent, 4);
|
||||
|
||||
EXPECT_EQ(valueAsBits(0.5f),
|
||||
valueAsBits(__llvm_libc::frexpf(16.0f, &exponent)));
|
||||
EXPECT_EQ(exponent, 5);
|
||||
EXPECT_EQ(valueAsBits(-0.5f),
|
||||
valueAsBits(__llvm_libc::frexpf(-16.0f, &exponent)));
|
||||
EXPECT_EQ(exponent, 5);
|
||||
|
||||
EXPECT_EQ(valueAsBits(0.5f),
|
||||
valueAsBits(__llvm_libc::frexpf(32.0f, &exponent)));
|
||||
EXPECT_EQ(exponent, 6);
|
||||
EXPECT_EQ(valueAsBits(-0.5f),
|
||||
valueAsBits(__llvm_libc::frexpf(-32.0f, &exponent)));
|
||||
EXPECT_EQ(exponent, 6);
|
||||
|
||||
EXPECT_EQ(valueAsBits(0.5f),
|
||||
valueAsBits(__llvm_libc::frexpf(64.0f, &exponent)));
|
||||
EXPECT_EQ(exponent, 7);
|
||||
EXPECT_EQ(valueAsBits(-0.5f),
|
||||
valueAsBits(__llvm_libc::frexpf(-64.0f, &exponent)));
|
||||
EXPECT_EQ(exponent, 7);
|
||||
}
|
||||
|
||||
TEST(FrexpTest, SomeIntegers) {
|
||||
int exponent;
|
||||
|
||||
EXPECT_EQ(valueAsBits(0.75f),
|
||||
valueAsBits(__llvm_libc::frexpf(24.0f, &exponent)));
|
||||
EXPECT_EQ(exponent, 5);
|
||||
EXPECT_EQ(valueAsBits(-0.75f),
|
||||
valueAsBits(__llvm_libc::frexpf(-24.0f, &exponent)));
|
||||
EXPECT_EQ(exponent, 5);
|
||||
|
||||
EXPECT_EQ(valueAsBits(0.625f),
|
||||
valueAsBits(__llvm_libc::frexpf(40.0f, &exponent)));
|
||||
EXPECT_EQ(exponent, 6);
|
||||
EXPECT_EQ(valueAsBits(-0.625f),
|
||||
valueAsBits(__llvm_libc::frexpf(-40.0f, &exponent)));
|
||||
EXPECT_EQ(exponent, 6);
|
||||
|
||||
EXPECT_EQ(valueAsBits(0.78125f),
|
||||
valueAsBits(__llvm_libc::frexpf(800.0f, &exponent)));
|
||||
EXPECT_EQ(exponent, 10);
|
||||
EXPECT_EQ(valueAsBits(-0.78125f),
|
||||
valueAsBits(__llvm_libc::frexpf(-800.0f, &exponent)));
|
||||
EXPECT_EQ(exponent, 10);
|
||||
}
|
||||
|
||||
TEST(FrexpfTest, InFloatRange) {
|
||||
using BitsType = Properties::BitsType;
|
||||
constexpr BitsType count = 1000000;
|
||||
constexpr BitsType step = UINT32_MAX / count;
|
||||
for (BitsType i = 0, v = 0; i <= count; ++i, v += step) {
|
||||
float x = valueFromBits(v);
|
||||
if (isnan(x) || isinf(x) || x == 0.0)
|
||||
continue;
|
||||
int exponent;
|
||||
float frac = __llvm_libc::frexpf(x, &exponent);
|
||||
|
||||
ASSERT_TRUE(__llvm_libc::fputil::abs(frac) < 1.0f);
|
||||
ASSERT_TRUE(__llvm_libc::fputil::abs(frac) >= 0.5f);
|
||||
}
|
||||
}
|
99
libc/test/src/math/logb_test.cpp
Normal file
99
libc/test/src/math/logb_test.cpp
Normal file
@ -0,0 +1,99 @@
|
||||
//===-- Unittests for logb ------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "include/math.h"
|
||||
#include "src/math/logb.h"
|
||||
#include "utils/FPUtil/BitPatterns.h"
|
||||
#include "utils/FPUtil/FloatOperations.h"
|
||||
#include "utils/FPUtil/FloatProperties.h"
|
||||
#include "utils/FPUtil/ManipulationFunctions.h"
|
||||
#include "utils/UnitTest/Test.h"
|
||||
|
||||
using __llvm_libc::fputil::valueAsBits;
|
||||
using __llvm_libc::fputil::valueFromBits;
|
||||
|
||||
using BitPatterns = __llvm_libc::fputil::BitPatterns<double>;
|
||||
using Properties = __llvm_libc::fputil::FloatProperties<double>;
|
||||
|
||||
TEST(LogbTest, SpecialNumbers) {
|
||||
EXPECT_EQ(
|
||||
BitPatterns::aQuietNaN,
|
||||
valueAsBits(__llvm_libc::logb(valueFromBits(BitPatterns::aQuietNaN))));
|
||||
EXPECT_EQ(BitPatterns::aNegativeQuietNaN,
|
||||
valueAsBits(__llvm_libc::logb(
|
||||
valueFromBits(BitPatterns::aNegativeQuietNaN))));
|
||||
|
||||
EXPECT_EQ(BitPatterns::aSignallingNaN,
|
||||
valueAsBits(
|
||||
__llvm_libc::logb(valueFromBits(BitPatterns::aSignallingNaN))));
|
||||
EXPECT_EQ(BitPatterns::aNegativeSignallingNaN,
|
||||
valueAsBits(__llvm_libc::logb(
|
||||
valueFromBits(BitPatterns::aNegativeSignallingNaN))));
|
||||
|
||||
EXPECT_EQ(BitPatterns::inf,
|
||||
valueAsBits(__llvm_libc::logb(valueFromBits(BitPatterns::inf))));
|
||||
EXPECT_EQ(BitPatterns::inf,
|
||||
valueAsBits(__llvm_libc::logb(valueFromBits(BitPatterns::negInf))));
|
||||
|
||||
EXPECT_EQ(BitPatterns::negInf,
|
||||
valueAsBits(__llvm_libc::logb(valueFromBits(BitPatterns::zero))));
|
||||
EXPECT_EQ(BitPatterns::negInf, valueAsBits(__llvm_libc::logb(
|
||||
valueFromBits(BitPatterns::negZero))));
|
||||
}
|
||||
|
||||
TEST(LogbTest, PowersOfTwo) {
|
||||
EXPECT_EQ(valueAsBits(0.0), valueAsBits(__llvm_libc::logb(1.0)));
|
||||
EXPECT_EQ(valueAsBits(0.0), valueAsBits(__llvm_libc::logb(-1.0)));
|
||||
|
||||
EXPECT_EQ(valueAsBits(1.0), valueAsBits(__llvm_libc::logb(2.0)));
|
||||
EXPECT_EQ(valueAsBits(1.0), valueAsBits(__llvm_libc::logb(-2.0)));
|
||||
|
||||
EXPECT_EQ(valueAsBits(2.0), valueAsBits(__llvm_libc::logb(4.0)));
|
||||
EXPECT_EQ(valueAsBits(2.0), valueAsBits(__llvm_libc::logb(-4.0)));
|
||||
|
||||
EXPECT_EQ(valueAsBits(3.0), valueAsBits(__llvm_libc::logb(8.0)));
|
||||
EXPECT_EQ(valueAsBits(3.0), valueAsBits(__llvm_libc::logb(-8.0)));
|
||||
|
||||
EXPECT_EQ(valueAsBits(4.0), valueAsBits(__llvm_libc::logb(16.0)));
|
||||
EXPECT_EQ(valueAsBits(4.0), valueAsBits(__llvm_libc::logb(-16.0)));
|
||||
|
||||
EXPECT_EQ(valueAsBits(5.0), valueAsBits(__llvm_libc::logb(32.0)));
|
||||
EXPECT_EQ(valueAsBits(5.0), valueAsBits(__llvm_libc::logb(-32.0)));
|
||||
}
|
||||
|
||||
TEST(LogbTest, SomeIntegers) {
|
||||
EXPECT_EQ(valueAsBits(1.0), valueAsBits(__llvm_libc::logb(3.0)));
|
||||
EXPECT_EQ(valueAsBits(1.0), valueAsBits(__llvm_libc::logb(-3.0)));
|
||||
|
||||
EXPECT_EQ(valueAsBits(2.0), valueAsBits(__llvm_libc::logb(7.0)));
|
||||
EXPECT_EQ(valueAsBits(2.0), valueAsBits(__llvm_libc::logb(-7.0)));
|
||||
|
||||
EXPECT_EQ(valueAsBits(3.0), valueAsBits(__llvm_libc::logb(10.0)));
|
||||
EXPECT_EQ(valueAsBits(3.0), valueAsBits(__llvm_libc::logb(-10.0)));
|
||||
|
||||
EXPECT_EQ(valueAsBits(4.0), valueAsBits(__llvm_libc::logb(31.0)));
|
||||
EXPECT_EQ(valueAsBits(4.0), valueAsBits(__llvm_libc::logb(-31.0)));
|
||||
|
||||
EXPECT_EQ(valueAsBits(5.0), valueAsBits(__llvm_libc::logb(55.0)));
|
||||
EXPECT_EQ(valueAsBits(5.0), valueAsBits(__llvm_libc::logb(-55.0)));
|
||||
}
|
||||
|
||||
TEST(LogbTest, InDoubleRange) {
|
||||
using BitsType = Properties::BitsType;
|
||||
constexpr BitsType count = 10000000;
|
||||
constexpr BitsType step = UINT64_MAX / count;
|
||||
for (BitsType i = 0, v = 0; i <= count; ++i, v += step) {
|
||||
double x = valueFromBits(v);
|
||||
if (isnan(x) || isinf(x) || x == 0.0)
|
||||
continue;
|
||||
|
||||
int exponent;
|
||||
__llvm_libc::fputil::frexp(x, exponent);
|
||||
ASSERT_TRUE(double(exponent) == __llvm_libc::logb(x) + 1.0);
|
||||
}
|
||||
}
|
99
libc/test/src/math/logbf_test.cpp
Normal file
99
libc/test/src/math/logbf_test.cpp
Normal file
@ -0,0 +1,99 @@
|
||||
//===-- Unittests for logbf -----------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "include/math.h"
|
||||
#include "src/math/logbf.h"
|
||||
#include "utils/FPUtil/BitPatterns.h"
|
||||
#include "utils/FPUtil/FloatOperations.h"
|
||||
#include "utils/FPUtil/FloatProperties.h"
|
||||
#include "utils/FPUtil/ManipulationFunctions.h"
|
||||
#include "utils/UnitTest/Test.h"
|
||||
|
||||
using __llvm_libc::fputil::valueAsBits;
|
||||
using __llvm_libc::fputil::valueFromBits;
|
||||
|
||||
using BitPatterns = __llvm_libc::fputil::BitPatterns<float>;
|
||||
using Properties = __llvm_libc::fputil::FloatProperties<float>;
|
||||
|
||||
TEST(LogbfTest, SpecialNumbers) {
|
||||
EXPECT_EQ(
|
||||
BitPatterns::aQuietNaN,
|
||||
valueAsBits(__llvm_libc::logbf(valueFromBits(BitPatterns::aQuietNaN))));
|
||||
EXPECT_EQ(BitPatterns::aNegativeQuietNaN,
|
||||
valueAsBits(__llvm_libc::logbf(
|
||||
valueFromBits(BitPatterns::aNegativeQuietNaN))));
|
||||
|
||||
EXPECT_EQ(BitPatterns::aSignallingNaN,
|
||||
valueAsBits(__llvm_libc::logbf(
|
||||
valueFromBits(BitPatterns::aSignallingNaN))));
|
||||
EXPECT_EQ(BitPatterns::aNegativeSignallingNaN,
|
||||
valueAsBits(__llvm_libc::logbf(
|
||||
valueFromBits(BitPatterns::aNegativeSignallingNaN))));
|
||||
|
||||
EXPECT_EQ(BitPatterns::inf,
|
||||
valueAsBits(__llvm_libc::logbf(valueFromBits(BitPatterns::inf))));
|
||||
EXPECT_EQ(BitPatterns::inf, valueAsBits(__llvm_libc::logbf(
|
||||
valueFromBits(BitPatterns::negInf))));
|
||||
|
||||
EXPECT_EQ(BitPatterns::negInf,
|
||||
valueAsBits(__llvm_libc::logbf(valueFromBits(BitPatterns::zero))));
|
||||
EXPECT_EQ(BitPatterns::negInf, valueAsBits(__llvm_libc::logbf(
|
||||
valueFromBits(BitPatterns::negZero))));
|
||||
}
|
||||
|
||||
TEST(LogbfTest, PowersOfTwo) {
|
||||
EXPECT_EQ(valueAsBits(0.0f), valueAsBits(__llvm_libc::logbf(1.0f)));
|
||||
EXPECT_EQ(valueAsBits(0.0f), valueAsBits(__llvm_libc::logbf(-1.0f)));
|
||||
|
||||
EXPECT_EQ(valueAsBits(1.0f), valueAsBits(__llvm_libc::logbf(2.0f)));
|
||||
EXPECT_EQ(valueAsBits(1.0f), valueAsBits(__llvm_libc::logbf(-2.0f)));
|
||||
|
||||
EXPECT_EQ(valueAsBits(2.0f), valueAsBits(__llvm_libc::logbf(4.0f)));
|
||||
EXPECT_EQ(valueAsBits(2.0f), valueAsBits(__llvm_libc::logbf(-4.0f)));
|
||||
|
||||
EXPECT_EQ(valueAsBits(3.0f), valueAsBits(__llvm_libc::logbf(8.0f)));
|
||||
EXPECT_EQ(valueAsBits(3.0f), valueAsBits(__llvm_libc::logbf(-8.0f)));
|
||||
|
||||
EXPECT_EQ(valueAsBits(4.0f), valueAsBits(__llvm_libc::logbf(16.0f)));
|
||||
EXPECT_EQ(valueAsBits(4.0f), valueAsBits(__llvm_libc::logbf(-16.0f)));
|
||||
|
||||
EXPECT_EQ(valueAsBits(5.0f), valueAsBits(__llvm_libc::logbf(32.0f)));
|
||||
EXPECT_EQ(valueAsBits(5.0f), valueAsBits(__llvm_libc::logbf(-32.0f)));
|
||||
}
|
||||
|
||||
TEST(LogbTest, SomeIntegers) {
|
||||
EXPECT_EQ(valueAsBits(1.0f), valueAsBits(__llvm_libc::logbf(3.0f)));
|
||||
EXPECT_EQ(valueAsBits(1.0f), valueAsBits(__llvm_libc::logbf(-3.0f)));
|
||||
|
||||
EXPECT_EQ(valueAsBits(2.0f), valueAsBits(__llvm_libc::logbf(7.0f)));
|
||||
EXPECT_EQ(valueAsBits(2.0f), valueAsBits(__llvm_libc::logbf(-7.0f)));
|
||||
|
||||
EXPECT_EQ(valueAsBits(3.0f), valueAsBits(__llvm_libc::logbf(10.0f)));
|
||||
EXPECT_EQ(valueAsBits(3.0f), valueAsBits(__llvm_libc::logbf(-10.0f)));
|
||||
|
||||
EXPECT_EQ(valueAsBits(4.0f), valueAsBits(__llvm_libc::logbf(31.0f)));
|
||||
EXPECT_EQ(valueAsBits(4.0f), valueAsBits(__llvm_libc::logbf(-31.0f)));
|
||||
|
||||
EXPECT_EQ(valueAsBits(5.0f), valueAsBits(__llvm_libc::logbf(55.0f)));
|
||||
EXPECT_EQ(valueAsBits(5.0f), valueAsBits(__llvm_libc::logbf(-55.0f)));
|
||||
}
|
||||
|
||||
TEST(LogbfTest, InDoubleRange) {
|
||||
using BitsType = Properties::BitsType;
|
||||
constexpr BitsType count = 10000000;
|
||||
constexpr BitsType step = UINT32_MAX / count;
|
||||
for (BitsType i = 0, v = 0; i <= count; ++i, v += step) {
|
||||
float x = valueFromBits(v);
|
||||
if (isnan(x) || isinf(x) || x == 0.0)
|
||||
continue;
|
||||
|
||||
int exponent;
|
||||
__llvm_libc::fputil::frexp(x, exponent);
|
||||
ASSERT_TRUE(float(exponent) == __llvm_libc::logbf(x) + 1.0);
|
||||
}
|
||||
}
|
130
libc/test/src/math/modf_test.cpp
Normal file
130
libc/test/src/math/modf_test.cpp
Normal file
@ -0,0 +1,130 @@
|
||||
//===-- Unittests for modf ------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "include/math.h"
|
||||
#include "src/math/modf.h"
|
||||
#include "utils/FPUtil/BitPatterns.h"
|
||||
#include "utils/FPUtil/FloatOperations.h"
|
||||
#include "utils/FPUtil/FloatProperties.h"
|
||||
#include "utils/UnitTest/Test.h"
|
||||
|
||||
using __llvm_libc::fputil::valueAsBits;
|
||||
using __llvm_libc::fputil::valueFromBits;
|
||||
|
||||
using BitPatterns = __llvm_libc::fputil::BitPatterns<double>;
|
||||
using Properties = __llvm_libc::fputil::FloatProperties<double>;
|
||||
|
||||
TEST(ModfTest, SpecialNumbers) {
|
||||
double integral;
|
||||
|
||||
EXPECT_EQ(BitPatterns::aQuietNaN,
|
||||
valueAsBits(__llvm_libc::modf(valueFromBits(BitPatterns::aQuietNaN),
|
||||
&integral)));
|
||||
EXPECT_EQ(BitPatterns::aNegativeQuietNaN,
|
||||
valueAsBits(__llvm_libc::modf(
|
||||
valueFromBits(BitPatterns::aNegativeQuietNaN), &integral)));
|
||||
|
||||
EXPECT_EQ(BitPatterns::aSignallingNaN,
|
||||
valueAsBits(__llvm_libc::modf(
|
||||
valueFromBits(BitPatterns::aSignallingNaN), &integral)));
|
||||
EXPECT_EQ(
|
||||
BitPatterns::aNegativeSignallingNaN,
|
||||
valueAsBits(__llvm_libc::modf(
|
||||
valueFromBits(BitPatterns::aNegativeSignallingNaN), &integral)));
|
||||
|
||||
EXPECT_EQ(BitPatterns::zero,
|
||||
valueAsBits(
|
||||
__llvm_libc::modf(valueFromBits(BitPatterns::inf), &integral)));
|
||||
EXPECT_EQ(valueAsBits(integral), BitPatterns::inf);
|
||||
|
||||
EXPECT_EQ(BitPatterns::negZero,
|
||||
valueAsBits(__llvm_libc::modf(valueFromBits(BitPatterns::negInf),
|
||||
&integral)));
|
||||
EXPECT_EQ(valueAsBits(integral), BitPatterns::negInf);
|
||||
|
||||
EXPECT_EQ(BitPatterns::zero,
|
||||
valueAsBits(__llvm_libc::modf(valueFromBits(BitPatterns::zero),
|
||||
&integral)));
|
||||
EXPECT_EQ(valueAsBits(integral), BitPatterns::zero);
|
||||
|
||||
EXPECT_EQ(BitPatterns::negZero,
|
||||
valueAsBits(__llvm_libc::modf(valueFromBits(BitPatterns::negZero),
|
||||
&integral)));
|
||||
EXPECT_EQ(valueAsBits(integral), BitPatterns::negZero);
|
||||
}
|
||||
|
||||
TEST(ModfTest, Integers) {
|
||||
double integral;
|
||||
|
||||
EXPECT_EQ(BitPatterns::zero, valueAsBits(__llvm_libc::modf(1.0, &integral)));
|
||||
EXPECT_EQ(valueAsBits(integral), valueAsBits(1.0));
|
||||
|
||||
EXPECT_EQ(BitPatterns::negZero,
|
||||
valueAsBits(__llvm_libc::modf(-1.0, &integral)));
|
||||
EXPECT_EQ(valueAsBits(integral), valueAsBits(-1.0));
|
||||
|
||||
EXPECT_EQ(BitPatterns::zero, valueAsBits(__llvm_libc::modf(10.0, &integral)));
|
||||
EXPECT_EQ(valueAsBits(integral), valueAsBits(10.0));
|
||||
|
||||
EXPECT_EQ(BitPatterns::negZero,
|
||||
valueAsBits(__llvm_libc::modf(-10.0, &integral)));
|
||||
EXPECT_EQ(valueAsBits(integral), valueAsBits(-10.0));
|
||||
|
||||
EXPECT_EQ(BitPatterns::zero,
|
||||
valueAsBits(__llvm_libc::modf(12345.0, &integral)));
|
||||
EXPECT_EQ(valueAsBits(integral), valueAsBits(12345.0));
|
||||
|
||||
EXPECT_EQ(BitPatterns::negZero,
|
||||
valueAsBits(__llvm_libc::modf(-12345.0, &integral)));
|
||||
EXPECT_EQ(valueAsBits(integral), valueAsBits(-12345.0));
|
||||
}
|
||||
|
||||
TEST(ModfTest, Fractions) {
|
||||
double integral;
|
||||
|
||||
EXPECT_EQ(valueAsBits(0.5), valueAsBits(__llvm_libc::modf(1.5, &integral)));
|
||||
EXPECT_EQ(valueAsBits(integral), valueAsBits(1.0));
|
||||
|
||||
EXPECT_EQ(valueAsBits(-0.5), valueAsBits(__llvm_libc::modf(-1.5, &integral)));
|
||||
EXPECT_EQ(valueAsBits(integral), valueAsBits(-1.0));
|
||||
|
||||
EXPECT_EQ(valueAsBits(0.75),
|
||||
valueAsBits(__llvm_libc::modf(10.75, &integral)));
|
||||
EXPECT_EQ(valueAsBits(integral), valueAsBits(10.0));
|
||||
|
||||
EXPECT_EQ(valueAsBits(-0.75),
|
||||
valueAsBits(__llvm_libc::modf(-10.75, &integral)));
|
||||
EXPECT_EQ(valueAsBits(integral), valueAsBits(-10.0));
|
||||
|
||||
EXPECT_EQ(valueAsBits(0.125),
|
||||
valueAsBits(__llvm_libc::modf(100.125, &integral)));
|
||||
EXPECT_EQ(valueAsBits(integral), valueAsBits(100.0));
|
||||
|
||||
EXPECT_EQ(valueAsBits(-0.125),
|
||||
valueAsBits(__llvm_libc::modf(-100.125, &integral)));
|
||||
EXPECT_EQ(valueAsBits(integral), valueAsBits(-100.0));
|
||||
}
|
||||
|
||||
TEST(ModfTest, InDoubleRange) {
|
||||
using BitsType = Properties::BitsType;
|
||||
constexpr BitsType count = 10000000;
|
||||
constexpr BitsType step = UINT64_MAX / count;
|
||||
for (BitsType i = 0, v = 0; i <= count; ++i, v += step) {
|
||||
double x = valueFromBits(v);
|
||||
if (isnan(x) || isinf(x) || x == 0.0) {
|
||||
// These conditions have been tested in other tests.
|
||||
continue;
|
||||
}
|
||||
|
||||
double integral;
|
||||
double frac = __llvm_libc::modf(x, &integral);
|
||||
ASSERT_TRUE(__llvm_libc::fputil::abs(frac) < 1.0);
|
||||
ASSERT_TRUE(__llvm_libc::fputil::trunc(x) == integral);
|
||||
ASSERT_TRUE(integral + frac == x);
|
||||
}
|
||||
}
|
135
libc/test/src/math/modff_test.cpp
Normal file
135
libc/test/src/math/modff_test.cpp
Normal file
@ -0,0 +1,135 @@
|
||||
//===-- Unittests for modfff
|
||||
//-----------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "include/math.h"
|
||||
#include "src/math/modff.h"
|
||||
#include "utils/FPUtil/BitPatterns.h"
|
||||
#include "utils/FPUtil/FloatOperations.h"
|
||||
#include "utils/FPUtil/FloatProperties.h"
|
||||
#include "utils/UnitTest/Test.h"
|
||||
|
||||
using __llvm_libc::fputil::valueAsBits;
|
||||
using __llvm_libc::fputil::valueFromBits;
|
||||
|
||||
using BitPatterns = __llvm_libc::fputil::BitPatterns<float>;
|
||||
using Properties = __llvm_libc::fputil::FloatProperties<float>;
|
||||
|
||||
TEST(ModffTest, SpecialNumbers) {
|
||||
float integral;
|
||||
|
||||
EXPECT_EQ(BitPatterns::aQuietNaN,
|
||||
valueAsBits(__llvm_libc::modff(
|
||||
valueFromBits(BitPatterns::aQuietNaN), &integral)));
|
||||
EXPECT_EQ(BitPatterns::aNegativeQuietNaN,
|
||||
valueAsBits(__llvm_libc::modff(
|
||||
valueFromBits(BitPatterns::aNegativeQuietNaN), &integral)));
|
||||
|
||||
EXPECT_EQ(BitPatterns::aSignallingNaN,
|
||||
valueAsBits(__llvm_libc::modff(
|
||||
valueFromBits(BitPatterns::aSignallingNaN), &integral)));
|
||||
EXPECT_EQ(
|
||||
BitPatterns::aNegativeSignallingNaN,
|
||||
valueAsBits(__llvm_libc::modff(
|
||||
valueFromBits(BitPatterns::aNegativeSignallingNaN), &integral)));
|
||||
|
||||
EXPECT_EQ(BitPatterns::zero,
|
||||
valueAsBits(__llvm_libc::modff(valueFromBits(BitPatterns::inf),
|
||||
&integral)));
|
||||
EXPECT_EQ(valueAsBits(integral), BitPatterns::inf);
|
||||
|
||||
EXPECT_EQ(BitPatterns::negZero,
|
||||
valueAsBits(__llvm_libc::modff(valueFromBits(BitPatterns::negInf),
|
||||
&integral)));
|
||||
EXPECT_EQ(valueAsBits(integral), BitPatterns::negInf);
|
||||
|
||||
EXPECT_EQ(BitPatterns::zero,
|
||||
valueAsBits(__llvm_libc::modff(valueFromBits(BitPatterns::zero),
|
||||
&integral)));
|
||||
EXPECT_EQ(valueAsBits(integral), BitPatterns::zero);
|
||||
|
||||
EXPECT_EQ(BitPatterns::negZero,
|
||||
valueAsBits(__llvm_libc::modff(valueFromBits(BitPatterns::negZero),
|
||||
&integral)));
|
||||
EXPECT_EQ(valueAsBits(integral), BitPatterns::negZero);
|
||||
}
|
||||
|
||||
TEST(ModffTest, Integers) {
|
||||
float integral;
|
||||
|
||||
EXPECT_EQ(BitPatterns::zero,
|
||||
valueAsBits(__llvm_libc::modff(1.0f, &integral)));
|
||||
EXPECT_EQ(valueAsBits(integral), valueAsBits(1.0f));
|
||||
|
||||
EXPECT_EQ(BitPatterns::negZero,
|
||||
valueAsBits(__llvm_libc::modff(-1.0f, &integral)));
|
||||
EXPECT_EQ(valueAsBits(integral), valueAsBits(-1.0f));
|
||||
|
||||
EXPECT_EQ(BitPatterns::zero,
|
||||
valueAsBits(__llvm_libc::modff(10.0f, &integral)));
|
||||
EXPECT_EQ(valueAsBits(integral), valueAsBits(10.0f));
|
||||
|
||||
EXPECT_EQ(BitPatterns::negZero,
|
||||
valueAsBits(__llvm_libc::modff(-10.0f, &integral)));
|
||||
EXPECT_EQ(valueAsBits(integral), valueAsBits(-10.0f));
|
||||
|
||||
EXPECT_EQ(BitPatterns::zero,
|
||||
valueAsBits(__llvm_libc::modff(12345.0f, &integral)));
|
||||
EXPECT_EQ(valueAsBits(integral), valueAsBits(12345.0f));
|
||||
|
||||
EXPECT_EQ(BitPatterns::negZero,
|
||||
valueAsBits(__llvm_libc::modff(-12345.0f, &integral)));
|
||||
EXPECT_EQ(valueAsBits(integral), valueAsBits(-12345.0f));
|
||||
}
|
||||
|
||||
TEST(ModfTest, Fractions) {
|
||||
float integral;
|
||||
|
||||
EXPECT_EQ(valueAsBits(0.5f),
|
||||
valueAsBits(__llvm_libc::modff(1.5f, &integral)));
|
||||
EXPECT_EQ(valueAsBits(integral), valueAsBits(1.0f));
|
||||
|
||||
EXPECT_EQ(valueAsBits(-0.5f),
|
||||
valueAsBits(__llvm_libc::modff(-1.5f, &integral)));
|
||||
EXPECT_EQ(valueAsBits(integral), valueAsBits(-1.0f));
|
||||
|
||||
EXPECT_EQ(valueAsBits(0.75f),
|
||||
valueAsBits(__llvm_libc::modff(10.75f, &integral)));
|
||||
EXPECT_EQ(valueAsBits(integral), valueAsBits(10.0f));
|
||||
|
||||
EXPECT_EQ(valueAsBits(-0.75f),
|
||||
valueAsBits(__llvm_libc::modff(-10.75f, &integral)));
|
||||
EXPECT_EQ(valueAsBits(integral), valueAsBits(-10.0f));
|
||||
|
||||
EXPECT_EQ(valueAsBits(0.125f),
|
||||
valueAsBits(__llvm_libc::modff(100.125f, &integral)));
|
||||
EXPECT_EQ(valueAsBits(integral), valueAsBits(100.0f));
|
||||
|
||||
EXPECT_EQ(valueAsBits(-0.125f),
|
||||
valueAsBits(__llvm_libc::modff(-100.125f, &integral)));
|
||||
EXPECT_EQ(valueAsBits(integral), valueAsBits(-100.0f));
|
||||
}
|
||||
|
||||
TEST(ModffTest, InDoubleRange) {
|
||||
using BitsType = Properties::BitsType;
|
||||
constexpr BitsType count = 10000000;
|
||||
constexpr BitsType step = UINT32_MAX / count;
|
||||
for (BitsType i = 0, v = 0; i <= count; ++i, v += step) {
|
||||
float x = valueFromBits(v);
|
||||
if (isnan(x) || isinf(x) || x == 0.0f) {
|
||||
// These conditions have been tested in other tests.
|
||||
continue;
|
||||
}
|
||||
|
||||
float integral;
|
||||
float frac = __llvm_libc::modff(x, &integral);
|
||||
ASSERT_TRUE(__llvm_libc::fputil::abs(frac) < 1.0f);
|
||||
ASSERT_TRUE(__llvm_libc::fputil::trunc(x) == integral);
|
||||
ASSERT_TRUE(integral + frac == x);
|
||||
}
|
||||
}
|
@ -11,6 +11,12 @@
|
||||
|
||||
#include "FloatProperties.h"
|
||||
|
||||
#include <float.h>
|
||||
|
||||
static_assert(
|
||||
FLT_RADIX == 2,
|
||||
"LLVM libc only supports radix 2 IEEE 754 floating point formats.");
|
||||
|
||||
namespace __llvm_libc {
|
||||
namespace fputil {
|
||||
|
||||
|
@ -4,6 +4,7 @@ add_header_library(
|
||||
BitPatterns.h
|
||||
FloatOperations.h
|
||||
FloatProperties.h
|
||||
ManipulationFunctions.h
|
||||
DEPS
|
||||
libc.utils.CPP.standalone_cpp
|
||||
)
|
||||
|
@ -57,26 +57,30 @@ static inline int getExponent(T x) {
|
||||
return getExponentFromBits(valueAsBits(x));
|
||||
}
|
||||
|
||||
template <typename BitsType> static inline bool bitsAreInf(BitsType bits) {
|
||||
using FPType = typename FloatType<BitsType>::Type;
|
||||
return ((bits & BitPatterns<FPType>::inf) == BitPatterns<FPType>::inf) &&
|
||||
((bits & FloatProperties<FPType>::mantissaMask) == 0);
|
||||
}
|
||||
|
||||
// Return true if x is infinity (positive or negative.)
|
||||
template <typename T,
|
||||
cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
|
||||
static inline bool isInf(T x) {
|
||||
using Properties = FloatProperties<T>;
|
||||
using BitsType = typename FloatProperties<T>::BitsType;
|
||||
BitsType bits = valueAsBits(x);
|
||||
return ((bits & BitPatterns<T>::inf) == BitPatterns<T>::inf) &&
|
||||
((bits & Properties::mantissaMask) == 0);
|
||||
return bitsAreInf(valueAsBits(x));
|
||||
}
|
||||
|
||||
template <typename BitsType> static inline bool bitsAreNaN(BitsType bits) {
|
||||
using FPType = typename FloatType<BitsType>::Type;
|
||||
return ((bits & BitPatterns<FPType>::inf) == BitPatterns<FPType>::inf) &&
|
||||
((bits & FloatProperties<FPType>::mantissaMask) != 0);
|
||||
}
|
||||
|
||||
// Return true if x is a NAN (quiet or signalling.)
|
||||
template <typename T,
|
||||
cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
|
||||
static inline bool isNaN(T x) {
|
||||
using Properties = FloatProperties<T>;
|
||||
using BitsType = typename FloatProperties<T>::BitsType;
|
||||
BitsType bits = valueAsBits(x);
|
||||
return ((bits & BitPatterns<T>::inf) == BitPatterns<T>::inf) &&
|
||||
((bits & Properties::mantissaMask) != 0);
|
||||
return bitsAreNaN(valueAsBits(x));
|
||||
}
|
||||
|
||||
template <typename BitsType> static inline bool bitsAreInfOrNaN(BitsType bits) {
|
||||
|
102
libc/utils/FPUtil/ManipulationFunctions.h
Normal file
102
libc/utils/FPUtil/ManipulationFunctions.h
Normal file
@ -0,0 +1,102 @@
|
||||
//===-- Common operations on floating point numbers -------------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "BitPatterns.h"
|
||||
#include "FloatOperations.h"
|
||||
#include "FloatProperties.h"
|
||||
|
||||
#include "utils/CPP/TypeTraits.h"
|
||||
|
||||
#ifndef LLVM_LIBC_UTILS_FPUTIL_MANIPULATION_FUNCTIONS_H
|
||||
#define LLVM_LIBC_UTILS_FPUTIL_MANIPULATION_FUNCTIONS_H
|
||||
|
||||
namespace __llvm_libc {
|
||||
namespace fputil {
|
||||
|
||||
template <typename T,
|
||||
cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
|
||||
static inline T frexp(T x, int &exp) {
|
||||
using Properties = FloatProperties<T>;
|
||||
using BitsType = typename Properties::BitsType;
|
||||
|
||||
auto bits = valueAsBits(x);
|
||||
if (bitsAreInfOrNaN(bits))
|
||||
return x;
|
||||
if (bitsAreZero(bits)) {
|
||||
exp = 0;
|
||||
return x;
|
||||
}
|
||||
|
||||
exp = getExponentFromBits(bits) + 1;
|
||||
|
||||
static constexpr BitsType resultExponent =
|
||||
Properties::exponentOffset - BitsType(1);
|
||||
// Capture the sign and mantissa part.
|
||||
bits &= (Properties::mantissaMask | Properties::signMask);
|
||||
// Insert the new exponent.
|
||||
bits |= (resultExponent << Properties::mantissaWidth);
|
||||
|
||||
return valueFromBits(bits);
|
||||
}
|
||||
|
||||
template <typename T,
|
||||
cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
|
||||
static inline T modf(T x, T &iptr) {
|
||||
auto bits = valueAsBits(x);
|
||||
if (bitsAreZero(bits) || bitsAreNaN(bits)) {
|
||||
iptr = x;
|
||||
return x;
|
||||
} else if (bitsAreInf(bits)) {
|
||||
iptr = x;
|
||||
return bits & FloatProperties<T>::signMask
|
||||
? valueFromBits(BitPatterns<T>::negZero)
|
||||
: valueFromBits(BitPatterns<T>::zero);
|
||||
} else {
|
||||
iptr = trunc(x);
|
||||
if (x == iptr) {
|
||||
// If x is already an integer value, then return zero with the right
|
||||
// sign.
|
||||
return bits & FloatProperties<T>::signMask
|
||||
? valueFromBits(BitPatterns<T>::negZero)
|
||||
: valueFromBits(BitPatterns<T>::zero);
|
||||
} else {
|
||||
return x - iptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T,
|
||||
cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
|
||||
static inline T copysign(T x, T y) {
|
||||
constexpr auto signMask = FloatProperties<T>::signMask;
|
||||
auto xbits = valueAsBits(x);
|
||||
auto ybits = valueAsBits(y);
|
||||
return valueFromBits((xbits & ~signMask) | (ybits & signMask));
|
||||
}
|
||||
|
||||
template <typename T,
|
||||
cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
|
||||
static inline T logb(T x) {
|
||||
auto bits = valueAsBits(x);
|
||||
if (bitsAreZero(bits)) {
|
||||
// TODO(Floating point exception): Raise div-by-zero exception.
|
||||
// TODO(errno): POSIX requires setting errno to ERANGE.
|
||||
return valueFromBits(BitPatterns<T>::negInf);
|
||||
} else if (bitsAreInf(bits)) {
|
||||
return valueFromBits(BitPatterns<T>::inf);
|
||||
} else if (bitsAreNaN(bits)) {
|
||||
return x;
|
||||
} else {
|
||||
return getExponentFromBits(bits);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace fputil
|
||||
} // namespace __llvm_libc
|
||||
|
||||
#endif // LLVM_LIBC_UTILS_FPUTIL_MANIPULATION_FUNCTIONS_H
|
Loading…
x
Reference in New Issue
Block a user