gfx/skia/trunk/src/utils/SkFloatUtils.h

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /*
     2  * Copyright 2012 Google Inc.
     3  *
     4  * Use of this source code is governed by a BSD-style license that can be
     5  * found in the LICENSE file.
     6  */
     8 #ifndef SkFloatUtils_DEFINED
     9 #define SkFloatUtils_DEFINED
    11 #include "SkTypes.h"
    12 #include <limits.h>
    13 #include <float.h>
    15 template <size_t size>
    16 class SkTypeWithSize {
    17 public:
    18     // Prevents using SkTypeWithSize<N> with non-specialized N.
    19     typedef void UInt;
    20 };
    22 template <>
    23 class SkTypeWithSize<32> {
    24 public:
    25     typedef uint32_t UInt;
    26 };
    28 template <>
    29 class SkTypeWithSize<64> {
    30 public:
    31     typedef uint64_t UInt;
    32 };
    34 template <typename RawType>
    35 struct SkNumericLimits {
    36     static const int digits = 0;
    37 };
    39 template <>
    40 struct SkNumericLimits<double> {
    41     static const int digits = DBL_MANT_DIG;
    42 };
    44 template <>
    45 struct SkNumericLimits<float> {
    46     static const int digits = FLT_MANT_DIG;
    47 };
    49 //See
    50 //http://stackoverflow.com/questions/17333/most-effective-way-for-float-and-double-comparison/3423299#3423299
    51 //http://code.google.com/p/googletest/source/browse/trunk/include/gtest/internal/gtest-internal.h
    52 //http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
    54 template <typename RawType, unsigned int ULPs>
    55 class SkFloatingPoint {
    56 public:
    57     /** Bits is a unsigned integer the same size as the floating point number. */
    58     typedef typename SkTypeWithSize<sizeof(RawType) * CHAR_BIT>::UInt Bits;
    60     /** # of bits in a number. */
    61     static const size_t kBitCount = CHAR_BIT * sizeof(RawType);
    63     /** # of fraction bits in a number. */
    64     static const size_t kFractionBitCount = SkNumericLimits<RawType>::digits - 1;
    66     /** # of exponent bits in a number. */
    67     static const size_t kExponentBitCount = kBitCount - 1 - kFractionBitCount;
    69     /** The mask for the sign bit. */
    70     static const Bits kSignBitMask = static_cast<Bits>(1) << (kBitCount - 1);
    72     /** The mask for the fraction bits. */
    73     static const Bits kFractionBitMask =
    74         ~static_cast<Bits>(0) >> (kExponentBitCount + 1);
    76     /** The mask for the exponent bits. */
    77     static const Bits kExponentBitMask = ~(kSignBitMask | kFractionBitMask);
    79     /** How many ULP's (Units in the Last Place) to tolerate when comparing. */
    80     static const size_t kMaxUlps = ULPs;
    82     /**
    83      *  Constructs a FloatingPoint from a raw floating-point number.
    84      *
    85      *  On an Intel CPU, passing a non-normalized NAN (Not a Number)
    86      *  around may change its bits, although the new value is guaranteed
    87      *  to be also a NAN.  Therefore, don't expect this constructor to
    88      *  preserve the bits in x when x is a NAN.
    89      */
    90     explicit SkFloatingPoint(const RawType& x) { fU.value = x; }
    92     /** Returns the exponent bits of this number. */
    93     Bits exponent_bits() const { return kExponentBitMask & fU.bits; }
    95     /** Returns the fraction bits of this number. */
    96     Bits fraction_bits() const { return kFractionBitMask & fU.bits; }
    98     /** Returns true iff this is NAN (not a number). */
    99     bool is_nan() const {
   100         // It's a NAN if both of the folloowing are true:
   101         // * the exponent bits are all ones
   102         // * the fraction bits are not all zero.
   103         return (exponent_bits() == kExponentBitMask) && (fraction_bits() != 0);
   104     }
   106     /**
   107      *  Returns true iff this number is at most kMaxUlps ULP's away from ths.
   108      *  In particular, this function:
   109      *   - returns false if either number is (or both are) NAN.
   110      *   - treats really large numbers as almost equal to infinity.
   111      *   - thinks +0.0 and -0.0 are 0 DLP's apart.
   112      */
   113     bool AlmostEquals(const SkFloatingPoint& rhs) const {
   114         // Any comparison operation involving a NAN must return false.
   115         if (is_nan() || rhs.is_nan()) return false;
   117         const Bits dist = DistanceBetweenSignAndMagnitudeNumbers(fU.bits,
   118                                                                  rhs.fU.bits);
   119         //SkDEBUGF(("(%f, %f, %d) ", u_.value_, rhs.u_.value_, dist));
   120         return dist <= kMaxUlps;
   121     }
   123 private:
   124     /** The data type used to store the actual floating-point number. */
   125     union FloatingPointUnion {
   126         /** The raw floating-point number. */
   127         RawType value;
   128         /** The bits that represent the number. */
   129         Bits bits;
   130     };
   132     /**
   133      *  Converts an integer from the sign-and-magnitude representation to
   134      *  the biased representation. More precisely, let N be 2 to the
   135      *  power of (kBitCount - 1), an integer x is represented by the
   136      *  unsigned number x + N.
   137      *
   138      *  For instance,
   139      *
   140      *    -N + 1 (the most negative number representable using
   141      *           sign-and-magnitude) is represented by 1;
   142      *    0      is represented by N; and
   143      *    N - 1  (the biggest number representable using
   144      *           sign-and-magnitude) is represented by 2N - 1.
   145      *
   146      *  Read http://en.wikipedia.org/wiki/Signed_number_representations
   147      *  for more details on signed number representations.
   148      */
   149     static Bits SignAndMagnitudeToBiased(const Bits &sam) {
   150         if (kSignBitMask & sam) {
   151             // sam represents a negative number.
   152             return ~sam + 1;
   153         } else {
   154             // sam represents a positive number.
   155             return kSignBitMask | sam;
   156         }
   157     }
   159     /**
   160      *  Given two numbers in the sign-and-magnitude representation,
   161      *  returns the distance between them as an unsigned number.
   162      */
   163     static Bits DistanceBetweenSignAndMagnitudeNumbers(const Bits &sam1,
   164                                                        const Bits &sam2) {
   165         const Bits biased1 = SignAndMagnitudeToBiased(sam1);
   166         const Bits biased2 = SignAndMagnitudeToBiased(sam2);
   167         return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1);
   168     }
   170     FloatingPointUnion fU;
   171 };
   173 #endif

mercurial