mirror of
https://git.mirrors.martin98.com/https://github.com/google/googletest.git
synced 2025-08-01 09:41:58 +08:00
Use std::memcpy instead of a union to access floating point bits.
PiperOrigin-RevId: 752789717 Change-Id: I20d17677bc75d12fa50328feb2bdc5c25e852cc4
This commit is contained in:
parent
00b2154e8e
commit
59c924bc47
@ -290,17 +290,17 @@ class FloatingPoint {
|
|||||||
// around may change its bits, although the new value is guaranteed
|
// around may change its bits, although the new value is guaranteed
|
||||||
// to be also a NAN. Therefore, don't expect this constructor to
|
// to be also a NAN. Therefore, don't expect this constructor to
|
||||||
// preserve the bits in x when x is a NAN.
|
// preserve the bits in x when x is a NAN.
|
||||||
explicit FloatingPoint(const RawType& x) { u_.value_ = x; }
|
explicit FloatingPoint(RawType x) { memcpy(&bits_, &x, sizeof(x)); }
|
||||||
|
|
||||||
// Static methods
|
// Static methods
|
||||||
|
|
||||||
// Reinterprets a bit pattern as a floating-point number.
|
// Reinterprets a bit pattern as a floating-point number.
|
||||||
//
|
//
|
||||||
// This function is needed to test the AlmostEquals() method.
|
// This function is needed to test the AlmostEquals() method.
|
||||||
static RawType ReinterpretBits(const Bits bits) {
|
static RawType ReinterpretBits(Bits bits) {
|
||||||
FloatingPoint fp(0);
|
RawType fp;
|
||||||
fp.u_.bits_ = bits;
|
memcpy(&fp, &bits, sizeof(fp));
|
||||||
return fp.u_.value_;
|
return fp;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the floating-point number that represent positive infinity.
|
// Returns the floating-point number that represent positive infinity.
|
||||||
@ -309,16 +309,16 @@ class FloatingPoint {
|
|||||||
// Non-static methods
|
// Non-static methods
|
||||||
|
|
||||||
// Returns the bits that represents this number.
|
// Returns the bits that represents this number.
|
||||||
const Bits& bits() const { return u_.bits_; }
|
const Bits& bits() const { return bits_; }
|
||||||
|
|
||||||
// Returns the exponent bits of this number.
|
// Returns the exponent bits of this number.
|
||||||
Bits exponent_bits() const { return kExponentBitMask & u_.bits_; }
|
Bits exponent_bits() const { return kExponentBitMask & bits_; }
|
||||||
|
|
||||||
// Returns the fraction bits of this number.
|
// Returns the fraction bits of this number.
|
||||||
Bits fraction_bits() const { return kFractionBitMask & u_.bits_; }
|
Bits fraction_bits() const { return kFractionBitMask & bits_; }
|
||||||
|
|
||||||
// Returns the sign bit of this number.
|
// Returns the sign bit of this number.
|
||||||
Bits sign_bit() const { return kSignBitMask & u_.bits_; }
|
Bits sign_bit() const { return kSignBitMask & bits_; }
|
||||||
|
|
||||||
// Returns true if and only if this is NAN (not a number).
|
// Returns true if and only if this is NAN (not a number).
|
||||||
bool is_nan() const {
|
bool is_nan() const {
|
||||||
@ -338,17 +338,10 @@ class FloatingPoint {
|
|||||||
// a NAN must return false.
|
// a NAN must return false.
|
||||||
if (is_nan() || rhs.is_nan()) return false;
|
if (is_nan() || rhs.is_nan()) return false;
|
||||||
|
|
||||||
return DistanceBetweenSignAndMagnitudeNumbers(u_.bits_, rhs.u_.bits_) <=
|
return DistanceBetweenSignAndMagnitudeNumbers(bits_, rhs.bits_) <= kMaxUlps;
|
||||||
kMaxUlps;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// The data type used to store the actual floating-point number.
|
|
||||||
union FloatingPointUnion {
|
|
||||||
RawType value_; // The raw floating-point number.
|
|
||||||
Bits bits_; // The bits that represent the number.
|
|
||||||
};
|
|
||||||
|
|
||||||
// Converts an integer from the sign-and-magnitude representation to
|
// Converts an integer from the sign-and-magnitude representation to
|
||||||
// the biased representation. More precisely, let N be 2 to the
|
// the biased representation. More precisely, let N be 2 to the
|
||||||
// power of (kBitCount - 1), an integer x is represented by the
|
// power of (kBitCount - 1), an integer x is represented by the
|
||||||
@ -364,7 +357,7 @@ class FloatingPoint {
|
|||||||
//
|
//
|
||||||
// Read https://en.wikipedia.org/wiki/Signed_number_representations
|
// Read https://en.wikipedia.org/wiki/Signed_number_representations
|
||||||
// for more details on signed number representations.
|
// for more details on signed number representations.
|
||||||
static Bits SignAndMagnitudeToBiased(const Bits& sam) {
|
static Bits SignAndMagnitudeToBiased(Bits sam) {
|
||||||
if (kSignBitMask & sam) {
|
if (kSignBitMask & sam) {
|
||||||
// sam represents a negative number.
|
// sam represents a negative number.
|
||||||
return ~sam + 1;
|
return ~sam + 1;
|
||||||
@ -376,14 +369,13 @@ class FloatingPoint {
|
|||||||
|
|
||||||
// Given two numbers in the sign-and-magnitude representation,
|
// Given two numbers in the sign-and-magnitude representation,
|
||||||
// returns the distance between them as an unsigned number.
|
// returns the distance between them as an unsigned number.
|
||||||
static Bits DistanceBetweenSignAndMagnitudeNumbers(const Bits& sam1,
|
static Bits DistanceBetweenSignAndMagnitudeNumbers(Bits sam1, Bits sam2) {
|
||||||
const Bits& sam2) {
|
|
||||||
const Bits biased1 = SignAndMagnitudeToBiased(sam1);
|
const Bits biased1 = SignAndMagnitudeToBiased(sam1);
|
||||||
const Bits biased2 = SignAndMagnitudeToBiased(sam2);
|
const Bits biased2 = SignAndMagnitudeToBiased(sam2);
|
||||||
return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1);
|
return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1);
|
||||||
}
|
}
|
||||||
|
|
||||||
FloatingPointUnion u_;
|
Bits bits_; // The bits that represent the number.
|
||||||
};
|
};
|
||||||
|
|
||||||
// Typedefs the instances of the FloatingPoint template class that we
|
// Typedefs the instances of the FloatingPoint template class that we
|
||||||
|
Loading…
x
Reference in New Issue
Block a user