4.45014771701440202508199667279499186358524265859260511351695091228726223124931264069530541271189424317838013700808305231545782515453032382772695923684574304409936197089118747150815050941806048037511737832041185193533879641611520514874130831632725201246060231058690536206311752656217652146466431814205051640436322226680064743260560117135282915796422274554896821334728738317548403413978098469341510556195293821919814730032341053661708792231510873354131880491105553390278848567812190177545006298062245710295816371174594568773301103242116891776567137054973871082078224775842509670618916870627821633352993761380751142008862499795052791018709663463944015644907297315659352441231715398102212132212018470035807616260163568645811358486831521563686919762403704226016998291015625000000000000000000000000000000000e-308

(768 significant digits).

#include <math.h>
#include <assert.h>
#include <stdio.h>

int main() {
double x = (pow(2, 52) - 1) * 2.0 + 1.0;
assert(x != x - 1.0);

double mind = 1 * pow(2, -1023) * pow(2, -51);
assert(mind != 0.0);
assert(mind / 2 == 0.0);

long double a = mind * x;
long double b = mind * (x - 1);

printf("%.800Le\n", (a + b) / 2);

return 0;
}

On Tue, Mar 23, 2010 at 12:27 PM, Florian Loitsch <floitsc...@gmail.com>wrote:

> It's a pity that most of the time more than 700 bytes on the stack are
> wasted, but I don't see any easier solution. I agree with Erik (offline
> discussion) that ~780 bytes on the stack should not be a big issue since the
> memory is not initialized and we are not calling this function recursively.
> I vote for allocating the big buffer on the stack.
> btw: it would be nice to have one example of a halfway-case with 771
> digits. (Note that sprintf "%.771e" gives a number with 771 precision
> digits).
> // florian
>
> On Mon, Mar 22, 2010 at 7:53 PM, Sergey Ryazanov <se...@google.com> wrote:
>
>> It seems that strtod rounds a decimal to a closest number
>> representable in double ("24414062505131250" parses as
>> 24414062505131248 and "24414062505131250.0.....01" 24414062505131252).
>> As I get from GNU source code it uses "multipercision numbers" for
>> exact representation of numbers.
>>
>> Any double is representable as d*2^p where 0 <= d < 2^53 and ... < p
>> <= -1074 (considering subnormal numbers). Any positive double x has
>> exact decimal representation:
>> 1) if 0 < x < 1: not more than ~770 significant digits (2^53 * 5^1074)
>> 2) 2^53 < x < DBL_MAX: not more than 308 significant digits since it's
>> an integer and DBL_MAX ≈ 1.79769 × 10^308.
>> 3) 1 < x < 2^53: not more than 60 significant digits.
>> (significant digits doesn't include leading and trailing zeros).
>>
>> Let's we have a decimal with more than 770 significant digits. We want
>> to find a double closest to our number. Dropping other digits (as well
>> as changing them to any other digits) would give us right result
>> unless our number lays exactly between 2 adjacent doubles. Mean of 2
>> adjacent doubles may have not more that 771 digits (all other would be
>> zoros). If the first digits of our number are equal to the digits of
>> that number the result of rounding would depend on if the rest of
>> digits are zeros.
>>
>> So conclusion is following: If we preserve at least 771 significant
>> digits and replace any nonzero tail by '1' we would never change
>> behavior of strtod.
>>
>>
>> On Sat, Mar 20, 2010 at 7:56 PM,  <floitsc...@gmail.com> wrote:
>> > I will discuss the
>> > 100000000000000000000000.0000000000000000000000000000000000000000000001
>> > issue
>> > with the V8 team on monday.
>> > The way I see it we have two options:
>> > 1. Follow ECMA-262 and round down, thus being incompatible with older
>> > versions.
>> > 2. Fallback to a more expensive reading when there are more than 20
>> digits.
>> >
>> > Pros/Cons for 1:
>> > Pro: Basically nothing to do. That's what we have now.
>> > Cons: Incompatible and we might numbers the "wrong" way. On the other
>> hand
>> > these
>> > numbers have to be written by hand (toString/toExponential/toFixed will
>> > never
>> > produce a number that would make such problems). Therefore they are
>> > extremely
>> > rare.
>> >
>> > Pros/Cons for 2:
>> > Pro: Compatible with older variants of V8. Reading is correct. Might
>> > slightly
>> > simplify the fast case: the exponent would need to be in range -999 to
>> 999.
>> > Cons: we would need to keep/add a fallback method. Maybe a template
>> taking
>> > either a fixed-size buffer or a dynamic vector would do the trick,
>> though.
>> >
>> >
>> >
>> > http://codereview.chromium.org/1096002/diff/3002/4003
>> > File src/conversions.cc (right):
>> >
>> > http://codereview.chromium.org/1096002/diff/3002/4003#newcode109
>> > src/conversions.cc:109: bool operator != (EndMarker const& m) const {
>> > return !(*this == m); }
>> > On 2010/03/19 15:46:12, SeRya wrote:
>> >>
>> >> On 2010/03/18 20:34:22, Erik Corry wrote:
>> >> > Some funky C++ here :-).  return !end_; seems simpler, but perhaps
>> >
>> > this is
>> >>
>> >> > somehow better?
>> >
>> >> Just a canonical form of != which simplifies maintenance (IMHO).
>> >
>> > I'm with Erik here.
>> > I still don't understand how this actually types. (Although I'm by no
>> > means a C++ expert).
>> > Also operator-overloading should be rare in Google code.
>> > Why not Peek(), AtEnd(), etc?
>> > This said, I'm not very familiar with V8 coding practices.
>> >
>> > http://codereview.chromium.org/1096002/diff/3002/4003#newcode496
>> > src/conversions.cc:496: const int max_exponent = INT_MAX / 2;
>> > On 2010/03/19 15:46:12, SeRya wrote:
>> >>
>> >> On 2010/03/19 13:39:43, Florian Loitsch wrote:
>> >> > This seems to be too complicated. A decimal number without leading
>> >
>> > 0s may only
>> >>
>> >> > have a decimal exponent of ~-400 to ~+400 before ending up being
>> >
>> > infinite or
>> >>
>> >> 0.
>> >
>> >> 1<1000 zeros>e-1000 == 1.
>> >
>> > Right you are.
>> >
>> > http://codereview.chromium.org/1096002/diff/3002/4003#newcode519
>> > src/conversions.cc:519: if (exponent != 0) {
>> > On 2010/03/19 15:46:12, SeRya wrote:
>> >>
>> >> On 2010/03/19 13:39:43, Florian Loitsch wrote:
>> >> > not that it really matters, but you could copy the exponent
>> >
>> > characters while
>> >>
>> >> > reading them, and just stop after 4 digits.
>> >> > This way you could avoid this part here.
>> >
>> >> It would mean another chunk of code that which drop leading zeros and
>> >
>> > check for
>> >>
>> >> junk tail. I'd prefer to simplify for now and may be add this
>> >
>> > optimization
>> >>
>> >> later.
>> >
>> > my comment was based on the assumption that the read exponent was in
>> > range -400 to +400. So disregard it.
>> >
>> > http://codereview.chromium.org/1096002/diff/21004/27003#newcode298
>> > src/conversions.cc:298: // 1. currnet == end (other ops are not
>> > allowed), current != end.
>> > Are we sure there is at least one character?
>> > If yes assert it.
>> > If not, and it is legal to access current[0] of empty string, explain.
>> >
>> > http://codereview.chromium.org/1096002/diff/21004/27003#newcode330
>> > src/conversions.cc:330: buffer[buffer_pos++] = '-';
>> > It might make sense to move the hexadecimal reading into a separate
>> > function.
>> >
>> > http://codereview.chromium.org/1096002/diff/21004/27003#newcode405
>> > src/conversions.cc:405: if (current == end) return signed_zero;
>> > I think it makes more sense to structure as follows:
>> > if (current == end) {
>> >  if (significant_digits == 0 && !leading_zero) {
>> >    // String was ".".
>> >    return JUNK_STRING_VALUE;
>> >  } else {
>> >    goto parsing_done;
>> >  }
>> > }
>> > if (significant_digits == 0) {
>> >  octal = false;
>> >  ...
>> > }
>> >
>> > http://codereview.chromium.org/1096002/diff/21004/27003#newcode451
>> > src/conversions.cc:451: }
>> > How should "123e" be parsed when "trailing junk is enabled?
>> > as "123" or as JUNK_STRING_VALUE?
>> > If it's the latter, then this is fine.
>> >
>> > http://codereview.chromium.org/1096002/diff/21004/27003#newcode456
>> > src/conversions.cc:456: ++current;
>> > As before: should 123e+ be parsed as 123 or JUNK_STRING_VALUE when
>> > trailing junk is enabled.
>> >
>> > http://codereview.chromium.org/1096002
>> >
>>
>
>

-- 
v8-dev mailing list
v8-dev@googlegroups.com
http://groups.google.com/group/v8-dev

To unsubscribe from this group, send email to 
v8-dev+unsubscribegooglegroups.com or reply to this email with the words 
"REMOVE ME" as the subject.

Reply via email to