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 #include "wtf/text/WTFString.h"
     35 
     36 namespace WTF {
     37 
     38 enum RoundingSignificantFiguresType { RoundingSignificantFigures };
     39 enum RoundingDecimalPlacesType { RoundingDecimalPlaces };
     40 
     41 class WTF_EXPORT DecimalNumber {
     42 public:
     43     DecimalNumber(double d)
     44     {
     45         ASSERT(std::isfinite(d));
     46         dtoa(m_significand, d, m_sign, m_exponent, m_precision);
     47 
     48         ASSERT(m_precision);
     49         // Zero should always have exponent 0.
     50         ASSERT(m_significand[0] != '0' || !m_exponent);
     51         // No values other than zero should have a leading zero.
     52         ASSERT(m_significand[0] != '0' || m_precision == 1);
     53         // No values other than zero should have trailing zeros.
     54         ASSERT(m_significand[0] == '0' || m_significand[m_precision - 1] != '0');
     55     }
     56 
     57     DecimalNumber(double d, RoundingSignificantFiguresType, unsigned significantFigures)
     58     {
     59         ASSERT(std::isfinite(d));
     60         dtoaRoundSF(m_significand, d, significantFigures, m_sign, m_exponent, m_precision);
     61 
     62         ASSERT_WITH_SECURITY_IMPLICATION(significantFigures && significantFigures <= sizeof(DtoaBuffer));
     63         while (m_precision < significantFigures)
     64             m_significand[m_precision++] = '0';
     65 
     66         ASSERT(m_precision);
     67         // Zero should always have exponent 0.
     68         ASSERT(m_significand[0] != '0' || !m_exponent);
     69     }
     70 
     71     DecimalNumber(double d, RoundingDecimalPlacesType, unsigned decimalPlaces)
     72     {
     73         ASSERT(std::isfinite(d));
     74         dtoaRoundDP(m_significand, d, decimalPlaces, m_sign, m_exponent, m_precision);
     75 
     76         unsigned significantFigures = 1 + m_exponent + decimalPlaces;
     77         ASSERT_WITH_SECURITY_IMPLICATION(significantFigures && significantFigures <= sizeof(DtoaBuffer));
     78         while (m_precision < significantFigures)
     79             m_significand[m_precision++] = '0';
     80 
     81         ASSERT(m_precision);
     82         // Zero should always have exponent 0.
     83         ASSERT(m_significand[0] != '0' || !m_exponent);
     84     }
     85 
     86     unsigned bufferLengthForStringDecimal() const;
     87     unsigned bufferLengthForStringExponential() const;
     88 
     89     unsigned toStringDecimal(LChar* buffer, unsigned bufferLength) const;
     90     unsigned toStringExponential(LChar* buffer, unsigned bufferLength) const;
     91 
     92     bool sign() const { return m_sign; }
     93     int exponent() const { return m_exponent; }
     94     const char* significand() const { return m_significand; } // significand contains precision characters, is not null-terminated.
     95     unsigned precision() const { return m_precision; }
     96 
     97 private:
     98     bool m_sign;
     99     int m_exponent;
    100     DtoaBuffer m_significand;
    101     unsigned m_precision;
    102 };
    103 
    104 } // namespace WTF
    105 
    106 using WTF::DecimalNumber;
    107 using WTF::RoundingSignificantFigures;
    108 using WTF::RoundingDecimalPlaces;
    109 
    110 #endif // DecimalNumber_h
    111