/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ // Original file Copyright Crytek GMBH or its affiliates, used under license. #ifndef CRYINCLUDE_CRYCOMMON_CRY_VALIDNUMBER_H #define CRYINCLUDE_CRYCOMMON_CRY_VALIDNUMBER_H #pragma once //-------------------------------------------------------------------------------- // http://www.psc.edu/general/software/packages/ieee/ieee.html /* The IEEE standard for floating point arithmetic """""""""""""""""""""""""""""""""""""""""""""""" Single Precision """"""""""""""""" The IEEE single precision floating point standard representation requires a 32 bit word, which may be represented as numbered from 0 to 31, left to right. The first bit is the sign bit, S, the next eight bits are the exponent bits, 'E', and the final 23 bits are the fraction 'F': S EEEEEEEE FFFFFFFFFFFFFFFFFFFFFFF 0 1 8 9 31 The value V represented by the word may be determined as follows: * If E=255 and F is nonzero, then V=NaN ("Not a number") * If E=255 and F is zero and S is 1, then V=-Infinity * If E=255 and F is zero and S is 0, then V=Infinity * If 0(x)) #define FloatU32ExpMask (0xFF << 23) #define FloatU32FracMask ((1 << 23) - 1) #define FloatU32SignMask (1 << 31) #define F32NAN (0x7F800001) // Produces rock solid fp-exceptions. #define F32NAN_SAFE (FloatU32ExpMask | FloatU32FracMask) // This one is not triggering an fp-exception. #define DoubleU64(x) (*((uint64*) &(x))) #define DoubleU64ExpMask ((uint64)255 << 55) #define DoubleU64FracMask (((uint64)1 << 55) - (uint64)1) #define DoubleU64SignMask ((uint64)1 << 63) #if defined(__GNUC__) #define F64NAN (0x7FF0000000000001ULL) // Produces rock solid fp-exceptions. #else #define F64NAN (0x7FF0000000000001) // Produces rock solid fp-exceptions. #endif #define F64NAN_SAFE (DoubleU64ExpMask | DoubleU64FracMask) // This one is not triggering an fp-exception. //-------------------------------------------------------------------------------- ILINE bool NumberValid(const float& x) { return ((FloatU32(x) & FloatU32ExpMask) != FloatU32ExpMask); } ILINE bool NumberNAN(const float& x) { return (((FloatU32(x) & FloatU32ExpMask) == FloatU32ExpMask) && ((FloatU32(x) & FloatU32FracMask) != 0)); } ILINE bool NumberINF(const float& x) { return (((FloatU32(x) & FloatU32ExpMask) == FloatU32ExpMask) && ((FloatU32(x) & FloatU32FracMask) == 0)); } ILINE bool NumberDEN(const float& x) { return (((FloatU32(x) & FloatU32ExpMask) == 0) && ((FloatU32(x) & FloatU32FracMask) != 0)); } //-------------------------------------------------------------------------------- ILINE bool NumberValid(const double& x) { return ((DoubleU64(x) & DoubleU64ExpMask) != DoubleU64ExpMask); } ILINE bool NumberNAN(const double& x) { return (((DoubleU64(x) & DoubleU64ExpMask) == DoubleU64ExpMask) && ((DoubleU64(x) & DoubleU64FracMask) != 0)); } ILINE bool NumberINF(const double& x) { return (((DoubleU64(x) & DoubleU64ExpMask) == DoubleU64ExpMask) && ((DoubleU64(x) & DoubleU64FracMask) == 0)); } ILINE bool NumberDEN(const double& x) { return (((DoubleU64(x) & DoubleU64ExpMask) == 0) && ((DoubleU64(x) & DoubleU64FracMask) != 0)); } //-------------------------------------------------------------------------------- ILINE bool NumberValid(const int8 x) { return true; //integers are always valid } ILINE bool NumberValid(const uint8 x) { return true; //integers are always valid } ILINE bool NumberValid(const int16 x) { return true; //integers are always valid } ILINE bool NumberValid(const uint16 x) { return true; //integers are always valid } ILINE bool NumberValid(const int32 x) { return true; //integers are always valid } ILINE bool NumberValid(const uint32 x) { return true; //integers are always valid } ILINE bool NumberValid(const int64 x) { return true; //integers are always valid } ILINE bool NumberValid(const uint64 x) { return true; //integers are always valid } #endif // CRYINCLUDE_CRYCOMMON_CRY_VALIDNUMBER_H