![]() |
|
Message-ID: <aGYHi-GMMiYari-w@voyager> Date: Thu, 3 Jul 2025 06:31:07 +0200 From: Markus Wichmann <nullplan@....net> To: musl@...ts.openwall.com Cc: Michal Terepeta <michalt@...gle.com>, t5y-external <t5y-external@...gle.com> Subject: Re: Wrong formatting of doubles? Am Wed, Jul 02, 2025 at 10:58:23AM -0400 schrieb Rich Felker: > On Tue, Jul 01, 2025 at 09:46:10PM -0400, Rich Felker wrote: > > static int fmt_fp(FILE *f, long double y, int w, int p, int fl, int t, int ps) > > { > > - int bufsize = (ps==BIGLPRE) > > - ? (LDBL_MANT_DIG+28)/29 + 1 + // mantissa expansion > > - (LDBL_MAX_EXP+LDBL_MANT_DIG+28+8)/9 // exponent expansion > > - : (DBL_MANT_DIG+28)/29 + 1 + > > - (DBL_MAX_EXP+DBL_MANT_DIG+28+8)/9; > > + int max_mant_dig = (ps==BIGLPRE) ? LDBL_MANT_DIG : DBL_MANT_DIG; > > + int max_exp = (ps==BIGLPRE) ? LDBL_MAX_EXP : DBL_MAX_EXP; > > + int max_mant_slots = (max_mant_dig+28)/29 + 1; > > + int max_exp_slots = (max_exp+max_mant_dig+28+8)/9; > > + int bufsize = max_mant_slots + max_exp_slots; > > uint32_t big[bufsize]; > > uint32_t *a, *d, *r, *z; > > int e2=0, e, i, j, l; > > @@ -266,7 +266,7 @@ static int fmt_fp(FILE *f, long double y, int w, int p, int fl, int t, int ps) > > if (y) y *= 0x1p28, e2-=28; > > > > if (e2<0) a=r=z=big; > > - else a=r=z=big+sizeof(big)/sizeof(*big) - LDBL_MANT_DIG - 1; > > + else a=r=z=big+sizeof(big)/sizeof(*big) - max_mant_slots - 1; > > > > do { > > *z = y; > > -- > > 2.21.0 > > > > While nothing should change in the case of negative exponents, I also > did an empirical check with DBL_TRUE_MIN to check the space for > denormals, and we have 5 slots to spare. That tracks with my calculations. I would just look at it from the result: The buffer only needs to be big enough to contain the largest end result, right? The largest decimal expansion occurs at TRUE_MIN, which is 2^(MIN_EXP - MANT_DIG), which has MANT_DIG - MIN_EXP decimal places. So you need enough slots for that many digits, +1 for the pre-radix slot you always have, so in the end bufsize = (mant_dig - min_exp + 8)/9 + 1 And that results in a little bit less than what you calculate. type | yours | mine -----|-------|----- ld64 | 126 | 121 ld80 | 1835 | 1828 ld128| 1842 | 1833 > > The multiplication by 0x1p28 above is handled by the +28 in the > expression for max_exp_slots. > See, that is an intermediate result. The multiplication is not big enough to make the mantissa expansion require more pre-radix slots, so it doesn't change how much space is needed. It only changes how many slots the mantissa expansion might take, which is not important to printing TRUE_MIN. It is important to printing numbers with positive exponents, but only for keeping the right distance from the end of the buffer. Ciao, Markus
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.