fix incorrect folder name for julia-0.6.x
Former-commit-id: ef2c7401e0876f22d2f7762d182cfbcd5a7d9c70
This commit is contained in:
		
							
								
								
									
										256
									
								
								julia-0.6.3/share/julia/base/grisu/bignum.jl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										256
									
								
								julia-0.6.3/share/julia/base/grisu/bignum.jl
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,256 @@ | ||||
| # This file is a part of Julia, but is derived from | ||||
| # https://github.com/google/double-conversion which has the following license | ||||
| # | ||||
| # Copyright 2006-2014, the V8 project authors. All rights reserved. | ||||
| # Redistribution and use in source and binary forms, with or without | ||||
| # modification, are permitted provided that the following conditions are | ||||
| # met: | ||||
| # | ||||
| #     * Redistributions of source code must retain the above copyright | ||||
| #       notice, this list of conditions and the following disclaimer. | ||||
| #     * Redistributions in binary form must reproduce the above | ||||
| #       copyright notice, this list of conditions and the following | ||||
| #       disclaimer in the documentation and/or other materials provided | ||||
| #       with the distribution. | ||||
| #     * Neither the name of Google Inc. nor the names of its | ||||
| #       contributors may be used to endorse or promote products derived | ||||
| #       from this software without specific prior written permission. | ||||
| # | ||||
| # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||||
| # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||||
| # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||||
| # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||||
| # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||||
| # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||||
| # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||||
| # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||||
| # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
| # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||||
| # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  | ||||
| function normalizedexponent(significand, exponent::Int32) | ||||
|     significand = UInt64(significand) | ||||
|     while (significand & HiddenBit(Float64)) == 0 | ||||
|         significand <<= UInt64(1) | ||||
|         exponent -= Int32(1) | ||||
|     end | ||||
|     return exponent | ||||
| end | ||||
|  | ||||
| function bignumdtoa(v,mode,requested_digits::Int,buffer,bignums) | ||||
|     significand = _significand(v) | ||||
|     exponent = _exponent(v) | ||||
|     lower_boundary_is_closer = lowerboundaryiscloser(v) | ||||
|     need_boundary_deltas = mode == SHORTEST | ||||
|  | ||||
|     is_even = (significand & 1) == 0 | ||||
|     normalized_exponent = normalizedexponent(significand, exponent) | ||||
|     estimated_power = estimatepower(Int(normalized_exponent)) | ||||
|  | ||||
|     if mode == FIXED && -estimated_power - 1 > requested_digits | ||||
|         buffer[1] = 0 | ||||
|         len = 1 | ||||
|         decimal_point = -requested_digits | ||||
|         return true, len, decimal_point | ||||
|     end | ||||
|     num, den, minus, plus = bignums[1], bignums[2], bignums[3], bignums[4] | ||||
|     initialscaledstartvalues!(significand,exponent,lower_boundary_is_closer, | ||||
|                               estimated_power,need_boundary_deltas, | ||||
|                               num,den,minus,plus) | ||||
|     decimal_point = fixupmultiply10!(estimated_power,is_even,num,den,minus,plus) | ||||
|     if mode == SHORTEST | ||||
|         len = generateshortestdigits!(num,den,minus,plus,is_even,buffer) | ||||
|     elseif mode == FIXED | ||||
|         len, decimal_point = bignumtofixed!(requested_digits,num,den,buffer,decimal_point) | ||||
|     elseif mode == PRECISION | ||||
|         len, decimal_point = generatecounteddigits!(requested_digits,num,den,buffer,decimal_point) | ||||
|     end | ||||
|     buffer[len] = 0 | ||||
|     return true, len, decimal_point | ||||
| end | ||||
|  | ||||
| function generateshortestdigits!(num,den,minus,plus,is_even,buffer) | ||||
|     minus == plus && (plus = minus) | ||||
|     len = 1 | ||||
|     while true | ||||
|         digit = Bignums.dividemodulointbignum!(num,den) | ||||
|         buffer[len] = 0x30 + (digit % UInt8) | ||||
|         len += 1 | ||||
|         in_delta_room_minus = is_even ? | ||||
|             Bignums.lessequal(num,minus) : Bignums.less(num,minus) | ||||
|         in_delta_room_plus = is_even ? | ||||
|             Bignums.pluscompare(num,plus,den) >= 0: Bignums.pluscompare(num,plus,den) > 0 | ||||
|         if !in_delta_room_minus && !in_delta_room_plus | ||||
|             Bignums.times10!(num) | ||||
|             Bignums.times10!(minus) | ||||
|             minus != plus && Bignums.times10!(plus) | ||||
|         elseif in_delta_room_minus && in_delta_room_plus | ||||
|             compare = Bignums.pluscompare(num,num,den) | ||||
|             if compare < 0 | ||||
|             elseif compare > 0 | ||||
|                 buffer[len - 1] += 1 | ||||
|             else | ||||
|                 if (buffer[len - 1] - 0x30) % 2 == 0 | ||||
|                 else | ||||
|                     buffer[len - 1] += 1 | ||||
|                 end | ||||
|             end | ||||
|             return len | ||||
|         elseif in_delta_room_minus | ||||
|             return len | ||||
|         else | ||||
|             buffer[len - 1] += 1 | ||||
|             return len | ||||
|         end | ||||
|     end | ||||
| end | ||||
|  | ||||
| function generatecounteddigits!(count,num,den,buffer,decimal_point) | ||||
|     for i = 1:(count-1) | ||||
|         digit = Bignums.dividemodulointbignum!(num,den) | ||||
|         buffer[i] = 0x30 + (digit % UInt8) | ||||
|         Bignums.times10!(num) | ||||
|     end | ||||
|     digit = Bignums.dividemodulointbignum!(num,den) | ||||
|     if Bignums.pluscompare(num,num,den) >= 0 | ||||
|         digit += 1 | ||||
|     end | ||||
|     buffer[count] = 0x30 + (digit % UInt8) | ||||
|     for i = count:-1:2 | ||||
|         buffer[i] != 0x30 + 10 && break | ||||
|         buffer[i] = 0x30 | ||||
|         buffer[i - 1] += 1 | ||||
|     end | ||||
|     if buffer[1] == 0x30 + 10 | ||||
|         buffer[1] = 0x31 | ||||
|         decimal_point += 1 | ||||
|     end | ||||
|     len = count+1 | ||||
|     return len, decimal_point | ||||
| end | ||||
|  | ||||
| function bignumtofixed!(requested_digits,num,den,buffer,decimal_point) | ||||
|     if -decimal_point > requested_digits | ||||
|         decimal_point = -requested_digits | ||||
|         len = 1 | ||||
|         return len, decimal_point | ||||
|     elseif -decimal_point == requested_digits | ||||
|         Bignums.times10!(den) | ||||
|         if Bignums.pluscompare(num,num,den) >= 0 | ||||
|             buffer[1] = 0x31 | ||||
|             len = 2 | ||||
|             decimal_point += 1 | ||||
|         else | ||||
|             len = 1 | ||||
|         end | ||||
|         return len, decimal_point | ||||
|     else | ||||
|         needed_digits = decimal_point + requested_digits | ||||
|         len, decimal_point = generatecounteddigits!( | ||||
|               needed_digits,num,den,buffer,decimal_point) | ||||
|     end | ||||
|     return len, decimal_point | ||||
| end | ||||
|  | ||||
|  | ||||
| const k1Log10 = 0.30102999566398114 | ||||
| const kSignificandSize = SignificandSize(Float64) | ||||
| estimatepower(exponent::Int) = ceil(Int,(exponent + kSignificandSize - 1) * k1Log10 - 1e-10) | ||||
|  | ||||
| function init3!( | ||||
|         significand,exponent,estimated_power,need_boundary_deltas, | ||||
|         num,den,minus,plus) | ||||
|     Bignums.assignuint64!(num,UInt64(significand)) | ||||
|     Bignums.shiftleft!(num,exponent) | ||||
|     Bignums.assignpoweruint16!(den,UInt16(10),estimated_power) | ||||
|     if need_boundary_deltas | ||||
|         Bignums.shiftleft!(den,1) | ||||
|         Bignums.shiftleft!(num,1) | ||||
|         Bignums.assignuint16!(plus,UInt16(1)) | ||||
|         Bignums.shiftleft!(plus,exponent) | ||||
|         Bignums.assignuint16!(minus,UInt16(1)) | ||||
|         Bignums.shiftleft!(minus,exponent) | ||||
|     else | ||||
|         Bignums.zero!(plus) | ||||
|         Bignums.zero!(minus) | ||||
|     end | ||||
|     return | ||||
| end | ||||
|  | ||||
|  | ||||
| function init1!( | ||||
|         significand,exponent,estimated_power,need_boundary_deltas, | ||||
|         num,den,minus,plus) | ||||
|     Bignums.assignuint64!(num,UInt64(significand)) | ||||
|     Bignums.assignpoweruint16!(den,UInt16(10),estimated_power) | ||||
|     Bignums.shiftleft!(den,-exponent) | ||||
|     if need_boundary_deltas | ||||
|         Bignums.shiftleft!(den,1) | ||||
|         Bignums.shiftleft!(num,1) | ||||
|         Bignums.assignuint16!(plus,UInt16(1)) | ||||
|         Bignums.assignuint16!(minus,UInt16(1)) | ||||
|     else | ||||
|         Bignums.zero!(plus) | ||||
|         Bignums.zero!(minus) | ||||
|     end | ||||
|     return | ||||
| end | ||||
|  | ||||
| function init2!( | ||||
|         significand,exponent,estimated_power,need_boundary_deltas, | ||||
|         num,den,minus,plus) | ||||
|     power_ten = num | ||||
|     Bignums.assignpoweruint16!(power_ten,UInt16(10),-estimated_power) | ||||
|     if need_boundary_deltas | ||||
|         Bignums.assignbignum!(plus,power_ten) | ||||
|         Bignums.assignbignum!(minus,power_ten) | ||||
|     else | ||||
|         Bignums.zero!(plus) | ||||
|         Bignums.zero!(minus) | ||||
|     end | ||||
|     Bignums.multiplybyuint64!(num,UInt64(significand)) | ||||
|     Bignums.assignuint16!(den,UInt16(1)) | ||||
|     Bignums.shiftleft!(den,-exponent) | ||||
|     if need_boundary_deltas | ||||
|         Bignums.shiftleft!(num,1) | ||||
|         Bignums.shiftleft!(den,1) | ||||
|     end | ||||
|     return | ||||
| end | ||||
|  | ||||
| function initialscaledstartvalues!(significand, | ||||
|             exponent,lower_boundary_is_closer,estimated_power, | ||||
|             need_boundary_deltas,num,den,minus,plus) | ||||
|     if exponent >= 0 | ||||
|         init3!(significand, exponent, estimated_power, need_boundary_deltas,num,den,minus,plus) | ||||
|     elseif estimated_power >= 0 | ||||
|         init1!(significand, exponent, estimated_power, need_boundary_deltas,num,den,minus,plus) | ||||
|     else | ||||
|         init2!(significand, exponent, estimated_power, need_boundary_deltas,num,den,minus,plus) | ||||
|     end | ||||
|     if need_boundary_deltas && lower_boundary_is_closer | ||||
|         Bignums.shiftleft!(den,1) | ||||
|         Bignums.shiftleft!(num,1) | ||||
|         Bignums.shiftleft!(plus,1) | ||||
|     end | ||||
|     return | ||||
| end | ||||
|  | ||||
| function fixupmultiply10!(estimated_power,is_even,num,den,minus,plus) | ||||
|     in_range = is_even ? Bignums.pluscompare(num,plus,den) >= 0 : | ||||
|                          Bignums.pluscompare(num,plus,den) > 0 | ||||
|     if in_range | ||||
|         decimal_point = estimated_power + 1 | ||||
|     else | ||||
|         decimal_point = estimated_power | ||||
|         Bignums.times10!(num) | ||||
|         if minus == plus | ||||
|             Bignums.times10!(minus) | ||||
|             Bignums.assignbignum!(plus,minus) | ||||
|         else | ||||
|             Bignums.times10!(minus) | ||||
|             Bignums.times10!(plus) | ||||
|         end | ||||
|     end | ||||
|     return decimal_point | ||||
| end | ||||
							
								
								
									
										495
									
								
								julia-0.6.3/share/julia/base/grisu/bignums.jl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										495
									
								
								julia-0.6.3/share/julia/base/grisu/bignums.jl
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,495 @@ | ||||
| # This file is a part of Julia, but is derived from | ||||
| # https://github.com/google/double-conversion which has the following license | ||||
| # | ||||
| # Copyright 2006-2014, the V8 project authors. All rights reserved. | ||||
| # Redistribution and use in source and binary forms, with or without | ||||
| # modification, are permitted provided that the following conditions are | ||||
| # met: | ||||
| # | ||||
| #     * Redistributions of source code must retain the above copyright | ||||
| #       notice, this list of conditions and the following disclaimer. | ||||
| #     * Redistributions in binary form must reproduce the above | ||||
| #       copyright notice, this list of conditions and the following | ||||
| #       disclaimer in the documentation and/or other materials provided | ||||
| #       with the distribution. | ||||
| #     * Neither the name of Google Inc. nor the names of its | ||||
| #       contributors may be used to endorse or promote products derived | ||||
| #       from this software without specific prior written permission. | ||||
| # | ||||
| # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||||
| # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||||
| # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||||
| # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||||
| # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||||
| # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||||
| # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||||
| # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||||
| # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
| # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||||
| # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  | ||||
| module Bignums | ||||
|  | ||||
| import Base: ==, < | ||||
|  | ||||
| export Bignum | ||||
|  | ||||
| const kMaxSignificantBits = 3584 | ||||
|  | ||||
| const Chunk = UInt32 | ||||
| const DoubleChunk = UInt64 | ||||
|  | ||||
| const kChunkSize = sizeof(Chunk) * 8 | ||||
| const kDoubleChunkSize = sizeof(DoubleChunk) * 8 | ||||
| # With bigit size of 28 we loose some bits, but a double still fits easily | ||||
| # into two chunks, and more importantly we can use the Comba multiplication. | ||||
| const kBigitSize = 28 | ||||
| const kBigitMask = Chunk((1 << kBigitSize) - 1) | ||||
| # Every instance allocates kBigitLength chunks on the stack. Bignums cannot | ||||
| # grow. There are no checks if the stack-allocated space is sufficient. | ||||
| const kBigitCapacity = div(kMaxSignificantBits, kBigitSize) | ||||
|  | ||||
| mutable struct Bignum | ||||
|     bigits::Vector{UInt32} | ||||
|     used_digits::Int32 | ||||
|     exponent::Int32 | ||||
|     function Bignum() | ||||
|         bigits = Vector{UInt32}(kBigitCapacity) | ||||
|         @inbounds for i = 1:kBigitCapacity | ||||
|             bigits[i] = 0 | ||||
|         end | ||||
|         new(bigits,0,0) | ||||
|     end | ||||
| end | ||||
|  | ||||
| ==(a::Bignum,b::Bignum) = compare(a,b) == 0 | ||||
| <(a::Bignum,b::Bignum) = compare(a,b) < 0 | ||||
|  | ||||
| times10!(x::Bignum) = multiplybyuint32!(x,UInt32(10)) | ||||
|  | ||||
| plusequal(a,b,c) = pluscompare(a,b,c) == 0 | ||||
| pluslessequal(a,b,c) = pluscompare(a,b,c) <= 0 | ||||
| plusless(a,b,c) = pluscompare(a,b,c) < 0 | ||||
| lessequal(a::Bignum,b::Bignum) = compare(a,b) <= 0 | ||||
| less(a::Bignum,b::Bignum) = compare(a,b) < 0 | ||||
|  | ||||
| bigitlength(x::Bignum) = x.used_digits + x.exponent | ||||
|  | ||||
| bitsize(value) = 8 * sizeof(value) | ||||
|  | ||||
| function zero!(x::Bignum) | ||||
|     for i = 1:x.used_digits | ||||
|         @inbounds x.bigits[i] = 0 | ||||
|     end | ||||
|     x.used_digits = 0 | ||||
|     x.exponent = 0 | ||||
|     return | ||||
| end | ||||
|  | ||||
| function clamp!(x::Bignum) | ||||
|     @inbounds while (x.used_digits > 0 && x.bigits[x.used_digits] == 0) | ||||
|         x.used_digits -= 1 | ||||
|     end | ||||
|     x.used_digits == 0 && (x.exponent = 0) | ||||
|     return | ||||
| end | ||||
|  | ||||
| isclamped(x::Bignum) = x.used_digits == 0 || x.bigits[x.used_digits] != 0 | ||||
|  | ||||
| function align!(x::Bignum,other::Bignum) | ||||
|     @inbounds if x.exponent > other.exponent | ||||
|         zero_digits = x.exponent - other.exponent | ||||
|         for i = x.used_digits:-1:1 | ||||
|             x.bigits[i + zero_digits] = x.bigits[i] | ||||
|         end | ||||
|         for i = 1:zero_digits | ||||
|             x.bigits[i] = 0 | ||||
|         end | ||||
|         x.used_digits += zero_digits | ||||
|         x.exponent -= zero_digits | ||||
|     end | ||||
|     return | ||||
| end | ||||
|  | ||||
| function bigitshiftleft!(x::Bignum,shift_amount) | ||||
|     carry::UInt32 = 0 | ||||
|     @inbounds begin | ||||
|     for i = 1:x.used_digits | ||||
|         new_carry::Chunk = x.bigits[i] >> (kBigitSize - shift_amount) | ||||
|         x.bigits[i] = ((x.bigits[i] << shift_amount) + carry) & kBigitMask | ||||
|         carry = new_carry | ||||
|     end | ||||
|     if carry != 0 | ||||
|         x.bigits[x.used_digits+1] = carry | ||||
|         x.used_digits += 1 | ||||
|     end | ||||
|     end | ||||
|     return | ||||
| end | ||||
|  | ||||
| function subtracttimes!(x::Bignum,other::Bignum,factor) | ||||
|     if factor < 3 | ||||
|         for i = 1:factor | ||||
|             subtractbignum!(x,other) | ||||
|         end | ||||
|         return | ||||
|     end | ||||
|     borrow::Chunk = 0 | ||||
|     exponent_diff = other.exponent - x.exponent | ||||
|     @inbounds begin | ||||
|     for i = 1:other.used_digits | ||||
|         product::DoubleChunk = DoubleChunk(factor) * other.bigits[i] | ||||
|         remove::DoubleChunk = borrow + product | ||||
|         difference::Chunk = (x.bigits[i+exponent_diff] - (remove & kBigitMask)) % Chunk | ||||
|         x.bigits[i+exponent_diff] = difference & kBigitMask | ||||
|         borrow = ((difference >> (kChunkSize - 1)) + (remove >> kBigitSize)) % Chunk | ||||
|     end | ||||
|     for i = (other.used_digits + exponent_diff + 1):x.used_digits | ||||
|         borrow == 0 && return | ||||
|         difference::Chunk = x.bigits[i] - borrow | ||||
|         x.bigits[i] = difference & kBigitMask | ||||
|         borrow = difference >> (kChunkSize - 1) | ||||
|     end | ||||
|     end | ||||
|     clamp!(x) | ||||
| end | ||||
|  | ||||
| function assignuint16!(x::Bignum,value::UInt16) | ||||
|     zero!(x) | ||||
|     value == 0 && return | ||||
|     x.bigits[1] = value | ||||
|     x.used_digits = 1 | ||||
|     return | ||||
| end | ||||
|  | ||||
| const kUInt64Size = 64 | ||||
| function assignuint64!(x::Bignum,value::UInt64) | ||||
|     zero!(x) | ||||
|     value == 0 && return | ||||
|     needed_bigits = div(kUInt64Size,kBigitSize) + 1 | ||||
|     @inbounds for i = 1:needed_bigits | ||||
|         x.bigits[i] = value & kBigitMask | ||||
|         value >>= kBigitSize | ||||
|     end | ||||
|     x.used_digits = needed_bigits | ||||
|     clamp!(x) | ||||
| end | ||||
|  | ||||
| function assignbignum!(x::Bignum,other::Bignum) | ||||
|     x.exponent = other.exponent | ||||
|     @inbounds begin | ||||
|     for i = 1:other.used_digits | ||||
|         x.bigits[i] = other.bigits[i] | ||||
|     end | ||||
|     for i = (other.used_digits+1):x.used_digits | ||||
|         x.bigits[i] = 0 | ||||
|     end | ||||
|     end | ||||
|     x.used_digits = other.used_digits | ||||
|     return | ||||
| end | ||||
|  | ||||
| function adduint64!(x::Bignum,operand::UInt64) | ||||
|     operand == 0 && return | ||||
|     other = Bignum() | ||||
|     assignuint64!(other,operand) | ||||
|     addbignum!(x,other) | ||||
| end | ||||
|  | ||||
| function addbignum!(x::Bignum,other::Bignum) | ||||
|     align!(x,other) | ||||
|     carry::Chunk = 0 | ||||
|     bigit_pos = other.exponent - x.exponent | ||||
|     @inbounds for i = 1:other.used_digits | ||||
|         sum::Chunk = x.bigits[bigit_pos+1] + other.bigits[i] + carry | ||||
|         x.bigits[bigit_pos+1] = sum & kBigitMask | ||||
|         carry = sum >> kBigitSize | ||||
|         bigit_pos += 1 | ||||
|     end | ||||
|     @inbounds while carry != 0 | ||||
|         sum = x.bigits[bigit_pos+1] + carry | ||||
|         x.bigits[bigit_pos+1] = sum & kBigitMask | ||||
|         carry = sum >> kBigitSize | ||||
|         bigit_pos += 1 | ||||
|     end | ||||
|     x.used_digits = max(bigit_pos,x.used_digits) | ||||
|     return | ||||
| end | ||||
|  | ||||
| function subtractbignum!(x::Bignum,other::Bignum) | ||||
|     align!(x,other) | ||||
|     offset = other.exponent - x.exponent | ||||
|     borrow = Chunk(0) | ||||
|     @inbounds begin | ||||
|     for i = 1:other.used_digits | ||||
|         difference = x.bigits[i+offset] - other.bigits[i] - borrow | ||||
|         x.bigits[i+offset] = difference & kBigitMask | ||||
|         borrow = difference >> (kChunkSize - 1) | ||||
|     end | ||||
|     i = other.used_digits+1 | ||||
|     while borrow != 0 | ||||
|         difference = x.bigits[i+offset] - borrow | ||||
|         x.bigits[i+offset] = difference & kBigitMask | ||||
|         borrow = difference >> (kChunkSize - 1) | ||||
|         i += 1 | ||||
|     end | ||||
|     end | ||||
|     clamp!(x) | ||||
| end | ||||
|  | ||||
| function shiftleft!(x::Bignum,shift_amount) | ||||
|     x.used_digits == 0 && return | ||||
|     x.exponent += div(shift_amount,kBigitSize) | ||||
|     local_shift = shift_amount % kBigitSize | ||||
|     bigitshiftleft!(x,local_shift) | ||||
| end | ||||
|  | ||||
| function multiplybyuint32!(x::Bignum,factor::UInt32) | ||||
|     factor == 1 && return | ||||
|     if factor == 0 | ||||
|         zero!(x) | ||||
|         return | ||||
|     end | ||||
|     x.used_digits == 0 && return | ||||
|     carry::DoubleChunk = 0 | ||||
|     @inbounds begin | ||||
|     for i = 1:x.used_digits | ||||
|         product::DoubleChunk = (factor % DoubleChunk) * x.bigits[i] + carry | ||||
|         x.bigits[i] = (product & kBigitMask) % Chunk | ||||
|         carry = product >> kBigitSize | ||||
|     end | ||||
|     while carry != 0 | ||||
|         x.bigits[x.used_digits+1] = carry & kBigitMask | ||||
|         x.used_digits += 1 | ||||
|         carry >>= kBigitSize | ||||
|     end | ||||
|     end | ||||
|     return | ||||
| end | ||||
|  | ||||
| function multiplybyuint64!(x::Bignum,factor::UInt64) | ||||
|     factor == 1 && return | ||||
|     if factor == 0 | ||||
|         zero!(x) | ||||
|         return | ||||
|     end | ||||
|     carry::UInt64 = 0 | ||||
|     low::UInt64 = factor & 0xFFFFFFFF | ||||
|     high::UInt64 = factor >> 32 | ||||
|     @inbounds begin | ||||
|     for i = 1:x.used_digits | ||||
|         product_low::UInt64 = low * x.bigits[i] | ||||
|         product_high::UInt64 = high * x.bigits[i] | ||||
|         tmp::UInt64 = (carry & kBigitMask) + product_low | ||||
|         x.bigits[i] = tmp & kBigitMask | ||||
|         carry = (carry >> kBigitSize) + (tmp >> kBigitSize) + | ||||
|                 (product_high << (32 - kBigitSize)) | ||||
|     end | ||||
|     while carry != 0 | ||||
|         x.bigits[x.used_digits+1] = carry & kBigitMask | ||||
|         x.used_digits += 1 | ||||
|         carry >>= kBigitSize | ||||
|     end | ||||
|     end | ||||
|     return | ||||
| end | ||||
|  | ||||
| const kFive27 = UInt64(0x6765c793fa10079d) | ||||
| const kFive1 = UInt16(5) | ||||
| const kFive2 = UInt16(kFive1 * 5) | ||||
| const kFive3 = UInt16(kFive2 * 5) | ||||
| const kFive4 = UInt16(kFive3 * 5) | ||||
| const kFive5 = UInt16(kFive4 * 5) | ||||
| const kFive6 = UInt16(kFive5 * 5) | ||||
| const kFive7 = UInt32(kFive6 * 5) | ||||
| const kFive8 = UInt32(kFive7 * 5) | ||||
| const kFive9 = UInt32(kFive8 * 5) | ||||
| const kFive10 = UInt32(kFive9 * 5) | ||||
| const kFive11 = UInt32(kFive10 * 5) | ||||
| const kFive12 = UInt32(kFive11 * 5) | ||||
| const kFive13 = UInt32(kFive12 * 5) | ||||
| const kFive1_to_12 = UInt32[kFive1, kFive2, kFive3, kFive4, kFive5, kFive6, | ||||
|         kFive7, kFive8, kFive9, kFive10, kFive11, kFive12] | ||||
| function multiplybypoweroften!(x::Bignum,exponent) | ||||
|     exponent == 0 && return | ||||
|     x.used_digits == 0 && return | ||||
|     remaining_exponent = exponent | ||||
|     while remaining_exponent >= 27 | ||||
|         multiplybyuint64!(x,kFive27) | ||||
|         remaining_exponent -= 27 | ||||
|     end | ||||
|     while remaining_exponent >= 13 | ||||
|         multiplybyuint32!(x,kFive13) | ||||
|         remaining_exponent -= 13 | ||||
|     end | ||||
|     remaining_exponent > 0 && multiplybyuint32!(x, | ||||
|                             kFive1_to_12[remaining_exponent]) | ||||
|     shiftleft!(x,exponent) | ||||
| end | ||||
|  | ||||
| function square!(x::Bignum) | ||||
|     product_length = 2 * x.used_digits | ||||
|     (1 << (2 * (kChunkSize - kBigitSize))) <= x.used_digits && error("unimplemented") | ||||
|     accumulator::DoubleChunk = 0 | ||||
|     copy_offset = x.used_digits | ||||
|     @inbounds begin | ||||
|     for i = 1:x.used_digits | ||||
|         x.bigits[copy_offset + i] = x.bigits[i] | ||||
|     end | ||||
|     for i = 1:x.used_digits | ||||
|         bigit_index1 = i-1 | ||||
|         bigit_index2 = 0 | ||||
|         while bigit_index1 >= 0 | ||||
|             chunk1::Chunk = x.bigits[copy_offset + bigit_index1 + 1] | ||||
|             chunk2::Chunk = x.bigits[copy_offset + bigit_index2 + 1] | ||||
|             accumulator += (chunk1 % DoubleChunk) * chunk2 | ||||
|             bigit_index1 -= 1 | ||||
|             bigit_index2 += 1 | ||||
|         end | ||||
|         x.bigits[i] = (accumulator % Chunk) & kBigitMask | ||||
|         accumulator >>= kBigitSize | ||||
|     end | ||||
|     for i = x.used_digits+1:product_length | ||||
|         bigit_index1 = x.used_digits - 1 | ||||
|         bigit_index2 = i - bigit_index1 - 1 | ||||
|         while bigit_index2 < x.used_digits | ||||
|             chunk1::Chunk = x.bigits[copy_offset + bigit_index1 + 1] | ||||
|             chunk2::Chunk = x.bigits[copy_offset + bigit_index2 + 1] | ||||
|             accumulator += (chunk1 % DoubleChunk) * chunk2 | ||||
|             bigit_index1 -= 1 | ||||
|             bigit_index2 += 1 | ||||
|         end | ||||
|         x.bigits[i] = (accumulator % Chunk) & kBigitMask | ||||
|         accumulator >>= kBigitSize | ||||
|     end | ||||
|     end | ||||
|     x.used_digits = product_length | ||||
|     x.exponent *= 2 | ||||
|     clamp!(x) | ||||
| end | ||||
|  | ||||
| function assignpoweruint16!(x::Bignum,base::UInt16,power_exponent::Int) | ||||
|     if power_exponent == 0 | ||||
|         assignuint16!(x,UInt16(1)) | ||||
|         return | ||||
|     end | ||||
|     zero!(x) | ||||
|     shifts::Int = 0 | ||||
|     while base & UInt16(1) == UInt16(0) | ||||
|         base >>= UInt16(1) | ||||
|         shifts += 1 | ||||
|     end | ||||
|     bit_size::Int = 0 | ||||
|     tmp_base::Int= base | ||||
|     while tmp_base != 0 | ||||
|         tmp_base >>= 1 | ||||
|         bit_size += 1 | ||||
|     end | ||||
|     final_size = bit_size * power_exponent | ||||
|     mask::Int = 1 | ||||
|     while power_exponent >= mask | ||||
|         mask <<= 1 | ||||
|     end | ||||
|     mask >>= 2 | ||||
|     this_value::UInt64 = base | ||||
|     delayed_multiplication = false | ||||
|     max_32bits::UInt64 = 0xFFFFFFFF | ||||
|     while mask != 0 && this_value <= max_32bits | ||||
|         this_value *= this_value | ||||
|         if (power_exponent & mask) != 0 | ||||
|             base_bits_mask::UInt64 = ~(UInt64(1) << (64 - bit_size) - 1) | ||||
|             high_bits_zero = (this_value & base_bits_mask) == 0 | ||||
|             if high_bits_zero | ||||
|                 this_value *= base | ||||
|             else | ||||
|                 delayed_multiplication = true | ||||
|             end | ||||
|         end | ||||
|         mask >>= 1 | ||||
|     end | ||||
|     assignuint64!(x,this_value) | ||||
|     delayed_multiplication && multiplybyuint32!(x,UInt32(base)) | ||||
|     while mask != 0 | ||||
|         square!(x) | ||||
|         (power_exponent & mask) != 0 && multiplybyuint32!(x,UInt32(base)) | ||||
|         mask >>= 1 | ||||
|     end | ||||
|     shiftleft!(x,shifts * power_exponent) | ||||
| end | ||||
|  | ||||
| function dividemodulointbignum!(x::Bignum,other::Bignum) | ||||
|     bigitlength(x) < bigitlength(other) && return UInt16(0) | ||||
|     align!(x,other) | ||||
|     result::UInt16 = 0 | ||||
|     @inbounds begin | ||||
|     while bigitlength(x) > bigitlength(other) | ||||
|         result += x.bigits[x.used_digits] % UInt16 | ||||
|         subtracttimes!(x,other,x.bigits[x.used_digits]) | ||||
|     end | ||||
|     this_bigit::Chunk = x.bigits[x.used_digits] | ||||
|     other_bigit::Chunk = other.bigits[other.used_digits] | ||||
|     if other.used_digits == 1 | ||||
|         quotient = reinterpret(Int32,div(this_bigit,other_bigit)) | ||||
|         x.bigits[x.used_digits] = this_bigit - other_bigit * reinterpret(UInt32,quotient) | ||||
|         result += quotient % UInt16 | ||||
|         clamp!(x) | ||||
|         return result | ||||
|     end | ||||
|     end | ||||
|     division_estimate = reinterpret(Int32,div(this_bigit,other_bigit+Chunk(1))) | ||||
|     result += division_estimate % UInt16 | ||||
|     subtracttimes!(x,other,division_estimate) | ||||
|     other_bigit * (division_estimate+1) > this_bigit && return result | ||||
|     while lessequal(other, x) | ||||
|         subtractbignum!(x,other) | ||||
|         result += UInt16(1) | ||||
|     end | ||||
|     return result | ||||
| end | ||||
|  | ||||
| function pluscompare(a::Bignum,b::Bignum,c::Bignum) | ||||
|     bigitlength(a) < bigitlength(b) && return pluscompare(b,a,c) | ||||
|     bigitlength(a) + 1 < bigitlength(c) && return -1 | ||||
|     bigitlength(a) > bigitlength(c) && return 1 | ||||
|     a.exponent >= bigitlength(b) && bigitlength(a) < bigitlength(c) && return -1 | ||||
|     borrow::Chunk = 0 | ||||
|     min_exponent = min(a.exponent,b.exponent,c.exponent) | ||||
|     for i = (bigitlength(c)-1):-1:min_exponent | ||||
|         chunk_a::Chunk = bigitat(a,i) | ||||
|         chunk_b::Chunk = bigitat(b,i) | ||||
|         chunk_c::Chunk = bigitat(c,i) | ||||
|         sum::Chunk = chunk_a + chunk_b | ||||
|         if sum > chunk_c + borrow | ||||
|             return 1 | ||||
|         else | ||||
|             borrow = chunk_c + borrow - sum | ||||
|             borrow > 1 && return -1 | ||||
|             borrow <<= kBigitSize | ||||
|         end | ||||
|     end | ||||
|     borrow == 0 && return 0 | ||||
|     return -1 | ||||
| end | ||||
|  | ||||
| function compare(a::Bignum,b::Bignum) | ||||
|     bigit_length_a = bigitlength(a) | ||||
|     bigit_length_b = bigitlength(b) | ||||
|     bigit_length_a < bigit_length_b && return -1 | ||||
|     bigit_length_a > bigit_length_b && return 1 | ||||
|     for i = (bigit_length_a-1):-1:min(a.exponent,b.exponent) | ||||
|         bigit_a::Chunk = bigitat(a,i) | ||||
|         bigit_b::Chunk = bigitat(b,i) | ||||
|         bigit_a < bigit_b && return -1 | ||||
|         bigit_a > bigit_b && return 1 | ||||
|     end | ||||
|     return 0 | ||||
| end | ||||
|  | ||||
| function bigitat(x::Bignum,index) | ||||
|     index >= bigitlength(x) && return Chunk(0) | ||||
|     index < x.exponent && return Chunk(0) | ||||
|     @inbounds ret = x.bigits[index - x.exponent+1]::Chunk | ||||
|     return ret | ||||
| end | ||||
|  | ||||
| end # module | ||||
							
								
								
									
										252
									
								
								julia-0.6.3/share/julia/base/grisu/fastfixed.jl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										252
									
								
								julia-0.6.3/share/julia/base/grisu/fastfixed.jl
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,252 @@ | ||||
| # This file is a part of Julia, but is derived from | ||||
| # https://github.com/google/double-conversion which has the following license | ||||
| # | ||||
| # Copyright 2006-2014, the V8 project authors. All rights reserved. | ||||
| # Redistribution and use in source and binary forms, with or without | ||||
| # modification, are permitted provided that the following conditions are | ||||
| # met: | ||||
| # | ||||
| #     * Redistributions of source code must retain the above copyright | ||||
| #       notice, this list of conditions and the following disclaimer. | ||||
| #     * Redistributions in binary form must reproduce the above | ||||
| #       copyright notice, this list of conditions and the following | ||||
| #       disclaimer in the documentation and/or other materials provided | ||||
| #       with the distribution. | ||||
| #     * Neither the name of Google Inc. nor the names of its | ||||
| #       contributors may be used to endorse or promote products derived | ||||
| #       from this software without specific prior written permission. | ||||
| # | ||||
| # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||||
| # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||||
| # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||||
| # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||||
| # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||||
| # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||||
| # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||||
| # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||||
| # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
| # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||||
| # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  | ||||
| const kDoubleSignificandSize = 53 | ||||
|  | ||||
| function filldigits32fixedlength(n1,requested_len,buffer,len) | ||||
|     for i = (requested_len-1):-1:0 | ||||
|         buffer[len+i] = 0x30 + n1 % 10 | ||||
|         n1 = div(n1,10) | ||||
|     end | ||||
|     return len + requested_len | ||||
| end | ||||
|  | ||||
| function filldigits32(n,buffer,len) | ||||
|     n_len = 0 | ||||
|     while n != 0 | ||||
|         digit = n % 10 | ||||
|         n = div(n,10) | ||||
|         buffer[len+n_len] = 0x30 + digit | ||||
|         n_len += 1 | ||||
|     end | ||||
|     i,j = len, len + n_len - 1 | ||||
|     while i < j | ||||
|         buffer[i], buffer[j] = buffer[j], buffer[i] | ||||
|         i += 1 | ||||
|         j -= 1 | ||||
|     end | ||||
|     return len + n_len | ||||
| end | ||||
|  | ||||
| function filldigits64fixedlength(n2,buffer,len) | ||||
|     kTen7 = 10000000 | ||||
|     part2 = n2 % kTen7 | ||||
|     n2 = div(n2,kTen7) | ||||
|     part0, part1 = divrem(n2,kTen7) | ||||
|     len = filldigits32fixedlength(part0, 3, buffer, len) | ||||
|     len = filldigits32fixedlength(part1, 7, buffer, len) | ||||
|     len = filldigits32fixedlength(part2, 7, buffer, len) | ||||
|     return len | ||||
| end | ||||
|  | ||||
| function filldigits64(n3,buffer,len) | ||||
|     kTen7 = 10000000 | ||||
|     part2 = n3 % kTen7 | ||||
|     n3 = div(n3,kTen7) | ||||
|     part0, part1 = divrem(n3,kTen7) | ||||
|     if part0 != 0 | ||||
|         len = filldigits32(part0, buffer, len) | ||||
|         len = filldigits32fixedlength(part1, 7, buffer, len) | ||||
|         len = filldigits32fixedlength(part2, 7, buffer, len) | ||||
|     elseif part1 != 0 | ||||
|         len = filldigits32(part1, buffer, len) | ||||
|         len = filldigits32fixedlength(part2, 7, buffer, len) | ||||
|     else | ||||
|         len = filldigits32(part2, buffer, len) | ||||
|     end | ||||
|     return len | ||||
| end | ||||
|  | ||||
| function roundup(buffer, len, decimal_point) | ||||
|     if len == 1 | ||||
|         buffer[1] = 0x31 | ||||
|         decimal_point = 1 | ||||
|         len = 2 | ||||
|         return len, decimal_point | ||||
|     end | ||||
|     buffer[len - 1] += 1 | ||||
|     for i = (len-1):-1:2 | ||||
|         buffer[i] != 0x30 + 10 && return len, decimal_point | ||||
|         buffer[i] = 0x30 | ||||
|         buffer[i - 1] += 1 | ||||
|     end | ||||
|     if buffer[1] == 0x30 + 10 | ||||
|         buffer[1] = 0x31 | ||||
|         decimal_point += 1 | ||||
|     end | ||||
|     return len, decimal_point | ||||
| end | ||||
|  | ||||
| function fillfractionals(fractionals, exponent, | ||||
|                          fractional_count, buffer, | ||||
|                          len, decimal_point) | ||||
|     if -exponent <= 64 | ||||
|         point = -exponent | ||||
|         for i = 1:fractional_count | ||||
|             fractionals == 0 && break | ||||
|             fractionals *= 5 | ||||
|             point -= 1 | ||||
|             digit = fractionals >> point | ||||
|             buffer[len] = 0x30 + digit | ||||
|             len += 1 | ||||
|             fractionals -= UInt64(digit) << point | ||||
|         end | ||||
|         if ((fractionals >> (point - 1)) & 1) == 1 | ||||
|             len, decimal_point = roundup(buffer, len, decimal_point) | ||||
|         end | ||||
|     else | ||||
|         fract128 = UInt128(fractionals) << 64 | ||||
|         fract128 = shift(fract128,-exponent - 64) | ||||
|         point = 128 | ||||
|         for i = 1:fractional_count | ||||
|             fract128 == 0 && break | ||||
|             fract128 *= 5 | ||||
|             point -= 1 | ||||
|             digit, fract128 = divrem2(fract128,point) | ||||
|             buffer[len] = 0x30 + digit | ||||
|             len += 1 | ||||
|         end | ||||
|         if bitat(fract128,point - 1) == 1 | ||||
|             len, decimal_point = roundup(buffer, len, decimal_point) | ||||
|         end | ||||
|     end | ||||
|     return len, decimal_point | ||||
| end | ||||
|  | ||||
| low(x) = UInt64(x&0xffffffffffffffff) | ||||
| high(x) = UInt64(x >>> 64) | ||||
| bitat(x::UInt128,y) = y >= 64 ? (Int32(high(x) >> (y-64)) & 1) : (Int32(low(x) >> y) & 1) | ||||
| function divrem2(x,power) | ||||
|     h = high(x) | ||||
|     l = low(x) | ||||
|     if power >= 64 | ||||
|         result = Int32(h >> (power - 64)) | ||||
|         h -= UInt64(result) << (power - 64) | ||||
|         return result, (UInt128(h) << 64) + l | ||||
|     else | ||||
|         part_low::UInt64 = l >> power | ||||
|         part_high::UInt64 = h << (64 - power) | ||||
|         result = Int32(part_low + part_high) | ||||
|         return result, UInt128(l - (part_low << power)) | ||||
|     end | ||||
| end | ||||
| function shift(x::UInt128,amt) | ||||
|     if amt == 0 | ||||
|       return x | ||||
|     elseif amt == -64 | ||||
|         return x << 64 | ||||
|     elseif amt == 64 | ||||
|         return x >> 64 | ||||
|     elseif amt <= 0 | ||||
|         h = high(x); l = low(x) | ||||
|         h <<= -amt | ||||
|         h += l >> (64 + amt) | ||||
|         l <<= -amt | ||||
|         return (UInt128(h) << 64) + l | ||||
|     else | ||||
|         h = high(x); l = low(x) | ||||
|         l >>= amt | ||||
|         l += h << (64 - amt) | ||||
|         h >>= amt | ||||
|         return (UInt128(h) << 64) + l | ||||
|     end | ||||
| end | ||||
|  | ||||
| function trimzeros(buffer, len, decimal_point) | ||||
|     while len > 1 && buffer[len - 1] == 0x30 | ||||
|         len -= 1 | ||||
|     end | ||||
|     first_non_zero::Int32 = 1 | ||||
|     while first_non_zero < len && buffer[first_non_zero] == 0x30 | ||||
|         first_non_zero += 1 | ||||
|     end | ||||
|     if first_non_zero != 1 | ||||
|         for i = first_non_zero:(len-1) | ||||
|             buffer[i - first_non_zero + 1] = buffer[i] | ||||
|         end | ||||
|         len -= first_non_zero-1 | ||||
|         decimal_point -= first_non_zero-1 | ||||
|     end | ||||
|     return len, decimal_point | ||||
| end | ||||
|  | ||||
| function fastfixedtoa(v,mode,fractional_count,buffer) | ||||
|     v = Float64(v) | ||||
|     significand::UInt64 = _significand(v) | ||||
|     exponent = _exponent(v) | ||||
|     exponent > 20 && return false, 0, 0 | ||||
|     fractional_count > 20 && return false, 0, 0 | ||||
|     len = 1 | ||||
|     if exponent + kDoubleSignificandSize > 64 | ||||
|         kFive17 = divisor = Int64(5)^17 | ||||
|         divisor_power = 17 | ||||
|         dividend = significand | ||||
|         if exponent > divisor_power | ||||
|             dividend <<= exponent - divisor_power | ||||
|             quotient = div(dividend,divisor) | ||||
|             remainder = (dividend % divisor) << divisor_power | ||||
|         else | ||||
|             divisor <<= divisor_power - exponent | ||||
|             quotient = div(dividend,divisor) | ||||
|             remainder = (dividend % divisor) << exponent | ||||
|         end | ||||
|         len = filldigits32(quotient, buffer, len) | ||||
|         len = filldigits64fixedlength(remainder, buffer, len) | ||||
|         decimal_point = len-1 | ||||
|     elseif exponent >= 0 | ||||
|         significand <<= exponent | ||||
|         len = filldigits64(significand, buffer, len) | ||||
|         decimal_point = len-1 | ||||
|     elseif exponent > -kDoubleSignificandSize | ||||
|         integrals = significand >> -exponent | ||||
|         fractionals = significand - (integrals << -exponent) | ||||
|         if integrals > 0xFFFFFFFF | ||||
|             len = filldigits64(integrals,buffer,len) | ||||
|         else | ||||
|             len = filldigits32(integrals%UInt32,buffer,len) | ||||
|         end | ||||
|         decimal_point = len-1 | ||||
|         len, decimal_point = fillfractionals(fractionals,exponent,fractional_count, | ||||
|                                              buffer,len, decimal_point) | ||||
|     elseif exponent < -128 | ||||
|         len = 1 | ||||
|         decimal_point = -fractional_count | ||||
|     else | ||||
|         decimal_point = 0 | ||||
|         len, decimal_point = fillfractionals(significand,exponent,fractional_count, | ||||
|                                              buffer,len, decimal_point) | ||||
|     end | ||||
|     len, decimal_point = trimzeros(buffer,len,decimal_point) | ||||
|     buffer[len] = 0 | ||||
|     if (len-1) == 0 | ||||
|         decimal_point = -fractional_count | ||||
|     end | ||||
|     return true, len, decimal_point | ||||
| end | ||||
							
								
								
									
										99
									
								
								julia-0.6.3/share/julia/base/grisu/fastprecision.jl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								julia-0.6.3/share/julia/base/grisu/fastprecision.jl
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,99 @@ | ||||
| # This file is a part of Julia, but is derived from | ||||
| # https://github.com/google/double-conversion which has the following license | ||||
| # | ||||
| # Copyright 2006-2014, the V8 project authors. All rights reserved. | ||||
| # Redistribution and use in source and binary forms, with or without | ||||
| # modification, are permitted provided that the following conditions are | ||||
| # met: | ||||
| # | ||||
| #     * Redistributions of source code must retain the above copyright | ||||
| #       notice, this list of conditions and the following disclaimer. | ||||
| #     * Redistributions in binary form must reproduce the above | ||||
| #       copyright notice, this list of conditions and the following | ||||
| #       disclaimer in the documentation and/or other materials provided | ||||
| #       with the distribution. | ||||
| #     * Neither the name of Google Inc. nor the names of its | ||||
| #       contributors may be used to endorse or promote products derived | ||||
| #       from this software without specific prior written permission. | ||||
| # | ||||
| # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||||
| # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||||
| # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||||
| # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||||
| # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||||
| # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||||
| # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||||
| # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||||
| # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
| # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||||
| # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  | ||||
| function roundweed(buffer,len,rest,tk,unit,kappa) | ||||
|     unit >= tk && return false, kappa | ||||
|     tk - unit <= unit && return false, kappa | ||||
|     tk - rest > rest && (tk - 2 * rest >= 2 * unit) && return true, kappa | ||||
|     if rest > unit && (tk - (rest - unit) <= (rest - unit)) | ||||
|         buffer[len-1] += 1 | ||||
|         for i = (len-1):-1:2 | ||||
|             buffer[i] != 0x30 + 10 && break | ||||
|             buffer[i] = 0x30 | ||||
|             buffer[i-1] += 1 | ||||
|         end | ||||
|         if buffer[1] == 0x30 + 10 | ||||
|             buffer[1] = 0x31 | ||||
|             kappa += 1 | ||||
|         end | ||||
|         return true, kappa | ||||
|     end | ||||
|     return false, kappa | ||||
| end | ||||
|  | ||||
| function digitgen(w,buffer,requested_digits=1000) | ||||
|     unit::UInt64 = 1 | ||||
|     one = Float(unit << -w.e, w.e) | ||||
|     integrals = w.s >> -one.e | ||||
|     fractionals = w.s & (one.s-1) | ||||
|     divisor, kappa = bigpowten(integrals, 64 + one.e) | ||||
|     len = 1 | ||||
|     rest = 0 | ||||
|     while kappa > 0 | ||||
|         digit = div(integrals,divisor) | ||||
|         buffer[len] = 0x30 + digit | ||||
|         len += 1 | ||||
|         requested_digits -= 1 | ||||
|         integrals %= divisor | ||||
|         kappa -= 1 | ||||
|         if requested_digits == 0 | ||||
|             rest = (UInt64(integrals) << -one.e) + fractionals | ||||
|             r, kappa = roundweed(buffer, len, rest, UInt64(divisor) << -one.e, | ||||
|                     unit,kappa) | ||||
|             return r, kappa, len | ||||
|         end | ||||
|         divisor = div(divisor,10) | ||||
|     end | ||||
|     while requested_digits > 0 && fractionals > unit | ||||
|         fractionals *= 10 | ||||
|         unit *= 10 | ||||
|         digit = fractionals >> -one.e | ||||
|         buffer[len] = 0x30 + digit | ||||
|         len += 1 | ||||
|         requested_digits -= 1 | ||||
|         fractionals &= one.s - 1 | ||||
|         kappa -= 1 | ||||
|     end | ||||
|     requested_digits != 0 && return false, kappa, len | ||||
|     r, kappa = roundweed(buffer,len,fractionals,one.s, | ||||
|                          unit,kappa) | ||||
|     return r, kappa, len | ||||
| end | ||||
|  | ||||
| function fastprecision(v, requested_digits, buffer = Vector{UInt8}(100)) | ||||
|     f = normalize(Float64(v)) | ||||
|     ten_mk_min_exp = kMinExp - (f.e + FloatSignificandSize) | ||||
|     ten_mk_max_exp = kMaxExp - (f.e + FloatSignificandSize) | ||||
|     cp = binexp_cache(ten_mk_min_exp,ten_mk_max_exp) | ||||
|     scaled_w = f * cp | ||||
|     r, kappa, len = digitgen(scaled_w,buffer,requested_digits) | ||||
|     decimal_exponent = -cp.de + kappa | ||||
|     return r, len, decimal_exponent+len-1 | ||||
| end | ||||
							
								
								
									
										118
									
								
								julia-0.6.3/share/julia/base/grisu/fastshortest.jl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								julia-0.6.3/share/julia/base/grisu/fastshortest.jl
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,118 @@ | ||||
| # This file is a part of Julia, but is derived from | ||||
| # https://github.com/google/double-conversion which has the following license | ||||
| # | ||||
| # Copyright 2006-2014, the V8 project authors. All rights reserved. | ||||
| # Redistribution and use in source and binary forms, with or without | ||||
| # modification, are permitted provided that the following conditions are | ||||
| # met: | ||||
| # | ||||
| #     * Redistributions of source code must retain the above copyright | ||||
| #       notice, this list of conditions and the following disclaimer. | ||||
| #     * Redistributions in binary form must reproduce the above | ||||
| #       copyright notice, this list of conditions and the following | ||||
| #       disclaimer in the documentation and/or other materials provided | ||||
| #       with the distribution. | ||||
| #     * Neither the name of Google Inc. nor the names of its | ||||
| #       contributors may be used to endorse or promote products derived | ||||
| #       from this software without specific prior written permission. | ||||
| # | ||||
| # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||||
| # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||||
| # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||||
| # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||||
| # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||||
| # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||||
| # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||||
| # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||||
| # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
| # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||||
| # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  | ||||
| const kMinExp = -60 | ||||
| const kMaxExp = -32 | ||||
|  | ||||
| function roundweed(buffer,len,rest,tk,unit,kappa,too_high::UInt64,unsafe_interval::UInt64) | ||||
|     small = too_high - unit | ||||
|     big = too_high + unit | ||||
|     while rest < small && | ||||
|             unsafe_interval - rest >= tk && | ||||
|             (rest + tk < small || | ||||
|             small - rest >= rest + tk - small) | ||||
|         buffer[len-1] -= 1 | ||||
|         rest += tk | ||||
|     end | ||||
|     if rest < big && | ||||
|         unsafe_interval - rest >= tk && | ||||
|         (rest + tk < big || | ||||
|         big - rest > rest + tk - big) | ||||
|         return false, kappa | ||||
|     end | ||||
|     return (2 * unit <= rest) && (rest <= unsafe_interval - 4 * unit), kappa | ||||
| end | ||||
|  | ||||
| const SmallPowersOfTen = [ | ||||
|         0, 1, 10, 100, 1000, 10000, 100000, | ||||
|         1000000, 10000000, 100000000, 1000000000] | ||||
|  | ||||
| function bigpowten(n,n_bits) | ||||
|     guess = (n_bits + 1) * 1233 >> 12 | ||||
|     guess += 1 | ||||
|     i = SmallPowersOfTen[guess+1] | ||||
|     return n < i ? (SmallPowersOfTen[guess], guess-1) : (i,guess) | ||||
| end | ||||
|  | ||||
| function digitgen(low,w,high,buffer) | ||||
|     unit::UInt64 = 1 | ||||
|     one = Float(unit << -w.e, w.e) | ||||
|     too_high = Float(high.s+unit,high.e) | ||||
|     unsafe_interval = too_high - Float(low.s-unit,low.e) | ||||
|     integrals = too_high.s >> -one.e | ||||
|     fractionals = too_high.s & (one.s-1) | ||||
|     divisor, kappa = bigpowten(integrals, 64 + one.e) | ||||
|     len = 1 | ||||
|     rest = UInt64(0) | ||||
|     while kappa > 0 | ||||
|         digit = div(integrals,divisor) | ||||
|         buffer[len] = 0x30 + digit | ||||
|         len += 1 | ||||
|         integrals %= divisor | ||||
|         kappa -= 1 | ||||
|         rest = (UInt64(integrals) << -one.e) + fractionals | ||||
|         if rest < unsafe_interval.s | ||||
|             r, kappa = roundweed(buffer, len, rest, UInt64(divisor) << -one.e, | ||||
|                         unit,kappa,(too_high - w).s,unsafe_interval.s) | ||||
|             return r, kappa, len | ||||
|         end | ||||
|         divisor = div(divisor,10) | ||||
|     end | ||||
|     while true | ||||
|         fractionals *= 10 | ||||
|         unit *= 10 | ||||
|         unsafe_interval = Float(unsafe_interval.s*10,unsafe_interval.e) | ||||
|         digit = fractionals >> -one.e | ||||
|         buffer[len] = 0x30 + digit | ||||
|         len += 1 | ||||
|         fractionals &= one.s - 1 | ||||
|         kappa -= 1 | ||||
|         if fractionals < unsafe_interval.s | ||||
|             r, kappa = roundweed(buffer,len,fractionals,one.s, | ||||
|                         unit,kappa,(too_high - w).s*unit,unsafe_interval.s) | ||||
|             return r, kappa, len | ||||
|         end | ||||
|     end | ||||
| end | ||||
|  | ||||
| function fastshortest(v, buffer = Vector{UInt8}(17)) | ||||
|     f = normalize(Float64(v)) | ||||
|     bound_minus, bound_plus = normalizedbound(v) | ||||
|     ten_mk_min_exp = kMinExp - (f.e + FloatSignificandSize) | ||||
|     ten_mk_max_exp = kMaxExp - (f.e + FloatSignificandSize) | ||||
|     cp = binexp_cache(ten_mk_min_exp,ten_mk_max_exp) | ||||
|     scaled_w = f * cp | ||||
|     scaled_bound_minus = bound_minus * cp | ||||
|     scaled_bound_plus = bound_plus * cp | ||||
|     r, kappa, len = digitgen(scaled_bound_minus,scaled_w, | ||||
|                              scaled_bound_plus,buffer) | ||||
|     decimal_exponent = -cp.de + kappa | ||||
|     return r, len, decimal_exponent+len-1 | ||||
| end | ||||
							
								
								
									
										256
									
								
								julia-0.6.3/share/julia/base/grisu/float.jl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										256
									
								
								julia-0.6.3/share/julia/base/grisu/float.jl
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,256 @@ | ||||
| # This file is a part of Julia, but is derived from | ||||
| # https://github.com/google/double-conversion which has the following license | ||||
| # | ||||
| # Copyright 2006-2014, the V8 project authors. All rights reserved. | ||||
| # Redistribution and use in source and binary forms, with or without | ||||
| # modification, are permitted provided that the following conditions are | ||||
| # met: | ||||
| # | ||||
| #     * Redistributions of source code must retain the above copyright | ||||
| #       notice, this list of conditions and the following disclaimer. | ||||
| #     * Redistributions in binary form must reproduce the above | ||||
| #       copyright notice, this list of conditions and the following | ||||
| #       disclaimer in the documentation and/or other materials provided | ||||
| #       with the distribution. | ||||
| #     * Neither the name of Google Inc. nor the names of its | ||||
| #       contributors may be used to endorse or promote products derived | ||||
| #       from this software without specific prior written permission. | ||||
| # | ||||
| # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||||
| # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||||
| # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||||
| # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||||
| # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||||
| # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||||
| # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||||
| # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||||
| # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
| # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||||
| # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  | ||||
| struct Float | ||||
|     s::UInt64 | ||||
|     e::Int32 | ||||
|     de::Int32 | ||||
| end | ||||
|  | ||||
| Float() = Float(0,0,0) | ||||
| Float(x,y) = Float(x,y,Int32(0)) | ||||
| Float(d::AbstractFloat) = Float(_significand(d), _exponent(d)) | ||||
|  | ||||
| # Consts | ||||
| const Float10MSBits = 0xFFC0000000000000 # used normalize(Float) | ||||
| const FloatSignMask = 0x8000000000000000 # used in normalize(Float) | ||||
| const FloatSignificandSize = Int32(64) | ||||
|  | ||||
| function normalize(v::Float) | ||||
|     f = v.s | ||||
|     e::Int32 = v.e | ||||
|     while (f & Float10MSBits) == 0 | ||||
|         f <<= 10 | ||||
|         e -= 10 | ||||
|     end | ||||
|     while (f & FloatSignMask) == 0 | ||||
|         f <<= 1 | ||||
|         e -= 1 | ||||
|     end | ||||
|     return Float(f,e) | ||||
| end | ||||
| function normalize(v::Float64) | ||||
|     s = _significand(v); e = _exponent(v) | ||||
|     while (s & HiddenBit(Float64)) == 0 | ||||
|         s <<= UInt64(1) | ||||
|         e -= Int32(1) | ||||
|     end | ||||
|     s <<= UInt64(FloatSignificandSize - SignificandSize(Float64)) | ||||
|     e -=  Int32( FloatSignificandSize - SignificandSize(Float64)) | ||||
|     return Float(s, e) | ||||
| end | ||||
|  | ||||
| # Float128 | ||||
| #DenormalExponent(::Type{Float128}) = Int32(-ExponentBias(Float128) + 1) | ||||
| #ExponentMask(::Type{Float128}) = 0x7fff0000000000000000000000000000 | ||||
| #PhysicalSignificandSize(::Type{Float128}) = Int32(112) | ||||
| #SignificandSize(::Type{Float128}) = Int32(113) | ||||
| #ExponentBias(::Type{Float128}) = Int32(0x00003fff + PhysicalSignificandSize(Float128)) | ||||
| #SignificandMask(::Type{Float128}) = 0x0000ffffffffffffffffffffffffffff | ||||
| #HiddenBit(::Type{Float128}) = 0x00010000000000000000000000000000 | ||||
| #uint_t(d::Float128) = reinterpret(UInt128,d) | ||||
| # Float64 | ||||
| DenormalExponent(::Type{Float64}) = Int32(-ExponentBias(Float64) + 1) | ||||
| ExponentMask(::Type{Float64}) = 0x7FF0000000000000 | ||||
| PhysicalSignificandSize(::Type{Float64}) = Int32(52) | ||||
| SignificandSize(::Type{Float64}) = Int32(53) | ||||
| ExponentBias(::Type{Float64}) = Int32(0x3FF + PhysicalSignificandSize(Float64)) | ||||
| SignificandMask(::Type{Float64}) = 0x000FFFFFFFFFFFFF | ||||
| HiddenBit(::Type{Float64}) = 0x0010000000000000 | ||||
| uint_t(d::Float64) = reinterpret(UInt64,d) | ||||
| # Float32 | ||||
| DenormalExponent(::Type{Float32}) = Int32(-ExponentBias(Float32) + 1) | ||||
| ExponentMask(::Type{Float32}) = 0x7F800000 | ||||
| PhysicalSignificandSize(::Type{Float32}) = Int32(23) | ||||
| SignificandSize(::Type{Float32}) = Int32(24) | ||||
| ExponentBias(::Type{Float32}) = Int32(0x7F + PhysicalSignificandSize(Float32)) | ||||
| SignificandMask(::Type{Float32}) = 0x007FFFFF | ||||
| HiddenBit(::Type{Float32}) = 0x00800000 | ||||
| uint_t(d::Float32) = reinterpret(UInt32,d) | ||||
| # Float16 | ||||
| DenormalExponent(::Type{Float16}) = Int32(-ExponentBias(Float16) + 1) | ||||
| ExponentMask(::Type{Float16}) = 0x7c00 | ||||
| PhysicalSignificandSize(::Type{Float16}) = Int32(10) | ||||
| SignificandSize(::Type{Float16}) = Int32(11) | ||||
| ExponentBias(::Type{Float16}) = Int32(0x000f + PhysicalSignificandSize(Float16)) | ||||
| SignificandMask(::Type{Float16}) = 0x03ff | ||||
| HiddenBit(::Type{Float16}) = 0x0400 | ||||
| uint_t(d::Float16) = reinterpret(UInt16,d) | ||||
|  | ||||
| function _exponent(d::T) where T<:AbstractFloat | ||||
|   isdenormal(d) && return DenormalExponent(T) | ||||
|   biased_e::Int32 = Int32((uint_t(d) & ExponentMask(T)) >> PhysicalSignificandSize(T)) | ||||
|   return Int32(biased_e - ExponentBias(T)) | ||||
| end | ||||
| function _significand(d::T) where T<:AbstractFloat | ||||
|   s = uint_t(d) & SignificandMask(T) | ||||
|   return !isdenormal(d) ? s + HiddenBit(T) : s | ||||
| end | ||||
| isdenormal{T<:AbstractFloat}(d::T) = (uint_t(d) & ExponentMask(T)) == 0 | ||||
|  | ||||
| function normalizedbound(f::AbstractFloat) | ||||
|     v = Float(_significand(f),_exponent(f)) | ||||
|     m_plus = normalize(Float((v.s << 1) + 1, v.e - 1)) | ||||
|     if lowerboundaryiscloser(f) | ||||
|         m_minus = Float((v.s << 2) - 1, v.e - 2) | ||||
|     else | ||||
|         m_minus = Float((v.s << 1) - 1, v.e - 1) | ||||
|     end | ||||
|     return Float(m_minus.s << (m_minus.e - m_plus.e), m_plus.e), m_plus | ||||
| end | ||||
| function lowerboundaryiscloser(f::T) where T<:AbstractFloat | ||||
|     physical_significand_is_zero = (uint_t(f) & SignificandMask(T)) == 0 | ||||
|     return physical_significand_is_zero && (_exponent(f) != DenormalExponent(T)) | ||||
| end | ||||
|  | ||||
| (-)(a::Float,b::Float) = Float(a.s - b.s,a.e,a.de) | ||||
|  | ||||
| const FloatM32 = 0xFFFFFFFF | ||||
|  | ||||
| function (*)(this::Float,other::Float) | ||||
|     a::UInt64 = this.s >> 32 | ||||
|     b::UInt64 = this.s & FloatM32 | ||||
|     c::UInt64 = other.s >> 32 | ||||
|     d::UInt64 = other.s & FloatM32 | ||||
|     ac::UInt64 = a * c | ||||
|     bc::UInt64 = b * c | ||||
|     ad::UInt64 = a * d | ||||
|     bd::UInt64 = b * d | ||||
|     tmp::UInt64 = (bd >> 32) + (ad & FloatM32) + (bc & FloatM32) | ||||
|     # By adding 1U << 31 to tmp we round the final result. | ||||
|     # Halfway cases will be round up. | ||||
|     tmp += UInt64(1) << 31 | ||||
|     result_f::UInt64 = ac + (ad >> 32) + (bc >> 32) + (tmp >> 32) | ||||
|     return Float(result_f,this.e + other.e + 64,this.de) | ||||
| end | ||||
|  | ||||
| const CachedPowers = Float[ | ||||
|   Float(0xfa8fd5a0081c0288, -1220, -348), | ||||
|   Float(0xbaaee17fa23ebf76, -1193, -340), | ||||
|   Float(0x8b16fb203055ac76, -1166, -332), | ||||
|   Float(0xcf42894a5dce35ea, -1140, -324), | ||||
|   Float(0x9a6bb0aa55653b2d, -1113, -316), | ||||
|   Float(0xe61acf033d1a45df, -1087, -308), | ||||
|   Float(0xab70fe17c79ac6ca, -1060, -300), | ||||
|   Float(0xff77b1fcbebcdc4f, -1034, -292), | ||||
|   Float(0xbe5691ef416bd60c, -1007, -284), | ||||
|   Float(0x8dd01fad907ffc3c, -980, -276), | ||||
|   Float(0xd3515c2831559a83, -954, -268), | ||||
|   Float(0x9d71ac8fada6c9b5, -927, -260), | ||||
|   Float(0xea9c227723ee8bcb, -901, -252), | ||||
|   Float(0xaecc49914078536d, -874, -244), | ||||
|   Float(0x823c12795db6ce57, -847, -236), | ||||
|   Float(0xc21094364dfb5637, -821, -228), | ||||
|   Float(0x9096ea6f3848984f, -794, -220), | ||||
|   Float(0xd77485cb25823ac7, -768, -212), | ||||
|   Float(0xa086cfcd97bf97f4, -741, -204), | ||||
|   Float(0xef340a98172aace5, -715, -196), | ||||
|   Float(0xb23867fb2a35b28e, -688, -188), | ||||
|   Float(0x84c8d4dfd2c63f3b, -661, -180), | ||||
|   Float(0xc5dd44271ad3cdba, -635, -172), | ||||
|   Float(0x936b9fcebb25c996, -608, -164), | ||||
|   Float(0xdbac6c247d62a584, -582, -156), | ||||
|   Float(0xa3ab66580d5fdaf6, -555, -148), | ||||
|   Float(0xf3e2f893dec3f126, -529, -140), | ||||
|   Float(0xb5b5ada8aaff80b8, -502, -132), | ||||
|   Float(0x87625f056c7c4a8b, -475, -124), | ||||
|   Float(0xc9bcff6034c13053, -449, -116), | ||||
|   Float(0x964e858c91ba2655, -422, -108), | ||||
|   Float(0xdff9772470297ebd, -396, -100), | ||||
|   Float(0xa6dfbd9fb8e5b88f, -369, -92), | ||||
|   Float(0xf8a95fcf88747d94, -343, -84), | ||||
|   Float(0xb94470938fa89bcf, -316, -76), | ||||
|   Float(0x8a08f0f8bf0f156b, -289, -68), | ||||
|   Float(0xcdb02555653131b6, -263, -60), | ||||
|   Float(0x993fe2c6d07b7fac, -236, -52), | ||||
|   Float(0xe45c10c42a2b3b06, -210, -44), | ||||
|   Float(0xaa242499697392d3, -183, -36), | ||||
|   Float(0xfd87b5f28300ca0e, -157, -28), | ||||
|   Float(0xbce5086492111aeb, -130, -20), | ||||
|   Float(0x8cbccc096f5088cc, -103, -12), | ||||
|   Float(0xd1b71758e219652c, -77, -4), | ||||
|   Float(0x9c40000000000000, -50, 4), | ||||
|   Float(0xe8d4a51000000000, -24, 12), | ||||
|   Float(0xad78ebc5ac620000, 3, 20), | ||||
|   Float(0x813f3978f8940984, 30, 28), | ||||
|   Float(0xc097ce7bc90715b3, 56, 36), | ||||
|   Float(0x8f7e32ce7bea5c70, 83, 44), | ||||
|   Float(0xd5d238a4abe98068, 109, 52), | ||||
|   Float(0x9f4f2726179a2245, 136, 60), | ||||
|   Float(0xed63a231d4c4fb27, 162, 68), | ||||
|   Float(0xb0de65388cc8ada8, 189, 76), | ||||
|   Float(0x83c7088e1aab65db, 216, 84), | ||||
|   Float(0xc45d1df942711d9a, 242, 92), | ||||
|   Float(0x924d692ca61be758, 269, 100), | ||||
|   Float(0xda01ee641a708dea, 295, 108), | ||||
|   Float(0xa26da3999aef774a, 322, 116), | ||||
|   Float(0xf209787bb47d6b85, 348, 124), | ||||
|   Float(0xb454e4a179dd1877, 375, 132), | ||||
|   Float(0x865b86925b9bc5c2, 402, 140), | ||||
|   Float(0xc83553c5c8965d3d, 428, 148), | ||||
|   Float(0x952ab45cfa97a0b3, 455, 156), | ||||
|   Float(0xde469fbd99a05fe3, 481, 164), | ||||
|   Float(0xa59bc234db398c25, 508, 172), | ||||
|   Float(0xf6c69a72a3989f5c, 534, 180), | ||||
|   Float(0xb7dcbf5354e9bece, 561, 188), | ||||
|   Float(0x88fcf317f22241e2, 588, 196), | ||||
|   Float(0xcc20ce9bd35c78a5, 614, 204), | ||||
|   Float(0x98165af37b2153df, 641, 212), | ||||
|   Float(0xe2a0b5dc971f303a, 667, 220), | ||||
|   Float(0xa8d9d1535ce3b396, 694, 228), | ||||
|   Float(0xfb9b7cd9a4a7443c, 720, 236), | ||||
|   Float(0xbb764c4ca7a44410, 747, 244), | ||||
|   Float(0x8bab8eefb6409c1a, 774, 252), | ||||
|   Float(0xd01fef10a657842c, 800, 260), | ||||
|   Float(0x9b10a4e5e9913129, 827, 268), | ||||
|   Float(0xe7109bfba19c0c9d, 853, 276), | ||||
|   Float(0xac2820d9623bf429, 880, 284), | ||||
|   Float(0x80444b5e7aa7cf85, 907, 292), | ||||
|   Float(0xbf21e44003acdd2d, 933, 300), | ||||
|   Float(0x8e679c2f5e44ff8f, 960, 308), | ||||
|   Float(0xd433179d9c8cb841, 986, 316), | ||||
|   Float(0x9e19db92b4e31ba9, 1013, 324), | ||||
|   Float(0xeb96bf6ebadf77d9, 1039, 332), | ||||
|   Float(0xaf87023b9bf0ee6b, 1066, 340)] | ||||
|  | ||||
| const CachedPowersLength = length(CachedPowers) | ||||
| const CachedPowersOffset = 348  # -1 * the first decimal_exponent. | ||||
| const D_1_LOG2_10 = 0.30102999566398114  #  1 / lg(10) | ||||
| # Difference between the decimal exponents in the table above. | ||||
| const DecimalExponentDistance = 8 | ||||
| const MinDecimalExponent = -348 | ||||
| const MaxDecimalExponent = 340 | ||||
|  | ||||
| function binexp_cache(min_exponent,max_exponent) | ||||
|     k = ceil(Integer,(min_exponent+63)*D_1_LOG2_10) | ||||
|     index = div(CachedPowersOffset+k-1,DecimalExponentDistance) + 1 | ||||
|     cp = CachedPowers[index+1] | ||||
|     return cp | ||||
| end | ||||
							
								
								
									
										190
									
								
								julia-0.6.3/share/julia/base/grisu/grisu.jl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										190
									
								
								julia-0.6.3/share/julia/base/grisu/grisu.jl
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,190 @@ | ||||
| # This file is a part of Julia. License is MIT: https://julialang.org/license | ||||
|  | ||||
| module Grisu | ||||
|  | ||||
| importall ..Base.Operators | ||||
|  | ||||
| export print_shortest | ||||
| export DIGITS, grisu | ||||
|  | ||||
| const SHORTEST = 1 | ||||
| const FIXED = 2 | ||||
| const PRECISION = 3 | ||||
|  | ||||
| const DIGITS = Vector{UInt8}(309+17) | ||||
|  | ||||
| include(joinpath("grisu", "float.jl")) | ||||
| include(joinpath("grisu", "fastshortest.jl")) | ||||
| include(joinpath("grisu", "fastprecision.jl")) | ||||
| include(joinpath("grisu", "fastfixed.jl")) | ||||
| include(joinpath("grisu", "bignums.jl")) | ||||
| include(joinpath("grisu", "bignum.jl")) | ||||
|  | ||||
| const BIGNUMS = [Bignums.Bignum(),Bignums.Bignum(),Bignums.Bignum(),Bignums.Bignum()] | ||||
|  | ||||
| function grisu(v::AbstractFloat,mode,requested_digits,buffer=DIGITS,bignums=BIGNUMS) | ||||
|     if signbit(v) | ||||
|         neg = true | ||||
|         v = -v | ||||
|     else | ||||
|         neg = false | ||||
|     end | ||||
|     if mode == PRECISION && requested_digits == 0 | ||||
|         buffer[1] = 0x00 | ||||
|         len = 0 | ||||
|         return 0, 0, neg | ||||
|     end | ||||
|     if v == 0.0 | ||||
|         buffer[1] = 0x30 | ||||
|         buffer[2] = 0x00 | ||||
|         len = point = 1 | ||||
|         return len, point, neg | ||||
|     end | ||||
|     if mode == SHORTEST | ||||
|         status,len,point = fastshortest(v,buffer) | ||||
|     elseif mode == FIXED | ||||
|         status,len,point = fastfixedtoa(v,0,requested_digits,buffer) | ||||
|     elseif mode == PRECISION | ||||
|         status,len,point = fastprecision(v,requested_digits,buffer) | ||||
|     end | ||||
|     status && return len-1, point, neg | ||||
|     status, len, point = bignumdtoa(v,mode,requested_digits,buffer,bignums) | ||||
|     return len-1, point, neg | ||||
| end | ||||
|  | ||||
| nanstr(x::AbstractFloat) = "NaN" | ||||
| nanstr(x::Float32) = "NaN32" | ||||
| nanstr(x::Float16) = "NaN16" | ||||
| infstr(x::AbstractFloat) = "Inf" | ||||
| infstr(x::Float32) = "Inf32" | ||||
| infstr(x::Float16) = "Inf16" | ||||
|  | ||||
| function _show(io::IO, x::AbstractFloat, mode, n::Int, typed, compact) | ||||
|     isnan(x) && return write(io, typed ? nanstr(x) : "NaN") | ||||
|     if isinf(x) | ||||
|         signbit(x) && write(io,'-') | ||||
|         write(io, typed ? infstr(x) : "Inf") | ||||
|         return | ||||
|     end | ||||
|     typed && isa(x,Float16) && write(io, "Float16(") | ||||
|     (len,pt,neg),buffer = grisu(x,mode,n),DIGITS | ||||
|     pdigits = pointer(buffer) | ||||
|     if mode == PRECISION | ||||
|         while len > 1 && buffer[len] == 0x30 | ||||
|             len -= 1 | ||||
|         end | ||||
|     end | ||||
|     neg && write(io,'-') | ||||
|     exp_form = pt <= -4 || pt > 6 | ||||
|     exp_form = exp_form || (pt >= len && abs(mod(x + 0.05, 10^(pt - len)) - 0.05) > 0.05) # see issue #6608 | ||||
|     if exp_form # .00001 to 100000. | ||||
|         # => #.#######e### | ||||
|         unsafe_write(io, pdigits, 1) | ||||
|         write(io, '.') | ||||
|         if len > 1 | ||||
|             unsafe_write(io, pdigits+1, len-1) | ||||
|         else | ||||
|             write(io, '0') | ||||
|         end | ||||
|         write(io, (typed && isa(x,Float32)) ? 'f' : 'e') | ||||
|         write(io, dec(pt-1)) | ||||
|         typed && isa(x,Float16) && write(io, ")") | ||||
|         return | ||||
|     elseif pt <= 0 | ||||
|         # => 0.00######## | ||||
|         write(io, "0.") | ||||
|         while pt < 0 | ||||
|             write(io, '0') | ||||
|             pt += 1 | ||||
|         end | ||||
|         unsafe_write(io, pdigits, len) | ||||
|     elseif pt >= len | ||||
|         # => ########00.0 | ||||
|         unsafe_write(io, pdigits, len) | ||||
|         while pt > len | ||||
|             write(io, '0') | ||||
|             len += 1 | ||||
|         end | ||||
|         write(io, ".0") | ||||
|     else # => ####.#### | ||||
|         unsafe_write(io, pdigits, pt) | ||||
|         write(io, '.') | ||||
|         unsafe_write(io, pdigits+pt, len-pt) | ||||
|     end | ||||
|     typed && !compact && isa(x,Float32) && write(io, "f0") | ||||
|     typed && isa(x,Float16) && write(io, ")") | ||||
|     nothing | ||||
| end | ||||
|  | ||||
| function Base.show(io::IO, x::Union{Float64,Float32}) | ||||
|     if get(io, :compact, false) | ||||
|         _show(io, x, PRECISION, 6, true, true) | ||||
|     else | ||||
|         _show(io, x, SHORTEST, 0, true, false) | ||||
|     end | ||||
| end | ||||
|  | ||||
| function Base.show(io::IO, x::Float16) | ||||
|     if get(io, :compact, false) | ||||
|         _show(io, x, PRECISION, 5, false, true) | ||||
|     else | ||||
|         _show(io, x, SHORTEST, 0, true, false) | ||||
|     end | ||||
| end | ||||
|  | ||||
| Base.print(io::IO, x::Float32) = _show(io, x, SHORTEST, 0, false, false) | ||||
| Base.print(io::IO, x::Float16) = _show(io, x, SHORTEST, 0, false, false) | ||||
|  | ||||
| # normal: | ||||
| #   0 < pt < len        ####.####           len+1 | ||||
| #   pt <= 0             0.000########       len-pt+1 | ||||
| #   len <= pt (dot)     ########000.        pt+1 | ||||
| #   len <= pt (no dot)  ########000         pt | ||||
| # exponential: | ||||
| #   pt <= 0             ########e-###       len+k+2 | ||||
| #   0 < pt              ########e###        len+k+1 | ||||
|  | ||||
| function _print_shortest(io::IO, x::AbstractFloat, dot::Bool, mode, n::Int) | ||||
|     isnan(x) && return write(io, "NaN") | ||||
|     x < 0 && write(io,'-') | ||||
|     isinf(x) && return write(io, "Inf") | ||||
|     (len,pt,neg),buffer = grisu(x,mode,n),DIGITS | ||||
|     pdigits = pointer(buffer) | ||||
|     e = pt-len | ||||
|     k = -9<=e<=9 ? 1 : 2 | ||||
|     if -pt > k+1 || e+dot > k+1 | ||||
|         # => ########e### | ||||
|         unsafe_write(io, pdigits+0, len) | ||||
|         write(io, 'e') | ||||
|         write(io, dec(e)) | ||||
|         return | ||||
|     elseif pt <= 0 | ||||
|         # => 0.000######## | ||||
|         write(io, "0.") | ||||
|         while pt < 0 | ||||
|             write(io, '0') | ||||
|             pt += 1 | ||||
|         end | ||||
|         unsafe_write(io, pdigits+0, len) | ||||
|     elseif e >= dot | ||||
|         # => ########000. | ||||
|         unsafe_write(io, pdigits+0, len) | ||||
|         while e > 0 | ||||
|             write(io, '0') | ||||
|             e -= 1 | ||||
|         end | ||||
|         if dot | ||||
|             write(io, '.') | ||||
|         end | ||||
|     else # => ####.#### | ||||
|         unsafe_write(io, pdigits+0, pt) | ||||
|         write(io, '.') | ||||
|         unsafe_write(io, pdigits+pt, len-pt) | ||||
|     end | ||||
|     nothing | ||||
| end | ||||
|  | ||||
| print_shortest(io::IO, x::AbstractFloat, dot::Bool) = _print_shortest(io, x, dot, SHORTEST, 0) | ||||
| print_shortest(io::IO, x::Union{AbstractFloat,Integer}) = print_shortest(io, float(x), false) | ||||
|  | ||||
| end # module | ||||
		Reference in New Issue
	
	Block a user