Home | History | Annotate | Download | only in wtf
      1 /*
      2  * Copyright (C) 2010 Apple Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
     17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #ifndef DecimalNumber_h
     27 #define DecimalNumber_h
     28 
     29 #include <math.h>
     30 
     31 #include "wtf/MathExtras.h"
     32 #include "wtf/WTFExport.h"
     33 #include "wtf/dtoa.h"
     34 
     35 namespace WTF {
     36 
     37 enum RoundingSignificantFiguresType { RoundingSignificantFigures };
     38 enum RoundingDecimalPlacesType { RoundingDecimalPlaces };
     39 
     40 class WTF_EXPORT DecimalNumber {
     41 public:
     42     DecimalNumber(double d)
     43     {
     44         ASSERT(std::isfinite(d));
     45         dtoa(m_significand, d, m_sign, m_exponent, m_precision);
     46 
     47         ASSERT(m_precision);
     48         // Zero should always have exponent 0.
     49         ASSERT(m_significand[0] != '0' || !m_exponent);
     50         // No values other than zero should have a leading zero.
     51         ASSERT(m_significand[0] != '0' || m_precision == 1);
     52         // No values other than zero should have trailing zeros.
     53         ASSERT(m_significand[0] == '0' || m_significand[m_precision - 1] != '0');
     54     }
     55 
     56     DecimalNumber(double d, RoundingSignificantFiguresType, unsigned significantFigures)
     57     {
     58         ASSERT(std::isfinite(d));
     59         dtoaRoundSF(m_significand, d, significantFigures, m_sign, m_exponent, m_precision);
     60 
     61         ASSERT_WITH_SECURITY_IMPLICATION(significantFigures && significantFigures <= sizeof(DtoaBuffer));
     62         while (m_precision < significantFigures)
     63             m_significand[m_precision++] = '0';
     64 
     65         ASSERT(m_precision);
     66         // Zero should always have exponent 0.
     67         ASSERT(m_significand[0] != '0' || !m_exponent);
     68     }
     69 
     70     DecimalNumber(double d, RoundingDecimalPlacesType, unsigned decimalPlaces)
     71     {
     72         ASSERT(std::isfinite(d));
     73         dtoaRoundDP(m_significand, d, decimalPlaces, m_sign, m_exponent, m_precision);
     74 
     75         unsigned significantFigures = 1 + m_exponent + decimalPlaces;
     76         ASSERT_WITH_SECURITY_IMPLICATION(significantFigures && significantFigures <= sizeof(DtoaBuffer));
     77         while (m_precision < significantFigures)
     78             m_significand[m_precision++] = '0';
     79 
     80         ASSERT(m_precision);
     81         // Zero should always have exponent 0.
     82         ASSERT(m_significand[0] != '0' || !m_exponent);
     83     }
     84 
     85     unsigned bufferLengthForStringDecimal() const;
     86     unsigned bufferLengthForStringExponential() const;
     87 
     88     unsigned toStringDecimal(LChar* buffer, unsigned bufferLength) const;
     89     unsigned toStringExponential(LChar* buffer, unsigned bufferLength) const;
     90 
     91     bool sign() const { return m_sign; }
     92     int exponent() const { return m_exponent; }
     93     const char* significand() const { return m_significand; } // significand contains precision characters, is not null-terminated.
     94     unsigned precision() const { return m_precision; }
     95 
     96 private:
     97     bool m_sign;
     98     int m_exponent;
     99     DtoaBuffer m_significand;
    100     unsigned m_precision;
    101 };
    102 
    103 } // namespace WTF
    104 
    105 using WTF::DecimalNumber;
    106 using WTF::RoundingSignificantFigures;
    107 using WTF::RoundingDecimalPlaces;
    108 
    109 #endif // DecimalNumber_h
    110