From: mhiroshi@tansei.cc.u-tokyo.ac.jp (H. Murakami)
Newsgroups: comp.unix.bsd,fj.os.386bsd
Subject: [386bsd] A cheap Japanese fix of vfprintf.c
Date: 10 Jan 93 01:29:16 GMT
Followup-To: comp.unix.bsd
Organization: Hokkaido Univ. However I am subject to tansei for JUNET.

To: comp.unix.bsd,fj.os.386bsd
Subject: [386bsd] A cheap Japanese fix of vfprintf.

If this patch if applied to the file /usr/src/lib/libc/stdio/vfprintf.c,
the value out of range trouble detected by the enquire will go away.

The value 0.01 is good for the values of not huge,
however, for the values of very large, 0.01 is to be changed
something 0.005 or 0.001 to pass the enquire test is detected.

======  The following is the output from enquire after this fix is applied.
======  It is a pity thing that there still remains two warnings.

Script started on Sun Jan 10 10:08:25 1993
% a.out
Produced by enquire version 4.3, CWI, Amsterdam
Compiler claims to be ANSI C level 1

SIZES
char = 8 bits, signed
short=16 int=32 long=32 float=32 double=64 bits 
long double=64 bits
char*=32 bits
int* =32 bits
func*=32 bits
Type size_t is unsigned int/long
Type size_t is unsigned int/long

ALIGNMENTS
char=1 short=2 int=4 long=4
float=4 double=4
long double=4
char*=4 int*=4 func*=4

CHARACTER ORDER
short: BA
int:   DCBA
long:  DCBA

PROPERTIES OF POINTERS
Char and int pointer formats seem identical
Char and function pointer formats seem identical
Strings are shared
Type ptrdiff_t is signed int/long

PROPERTIES OF INTEGRAL TYPES
Overflow of a short does not generate a trap
Maximum short = 32767 (= 2**15-1)
Minimum short = -32768
Overflow of an int does not generate a trap
Maximum int = 2147483647 (= 2**31-1)
Minimum int = -2147483648
Overflow of a long does not generate a trap
Maximum long = 2147483647 (= 2**31-1)
Minimum long = -2147483648
Maximum unsigned short = 65535
Maximum unsigned int = 4294967295
Maximum unsigned long = 4294967295

PROMOTIONS
unsigned short promotes to signed int/long
long+unsigned gives unsigned int/long

PROPERTIES OF FLOAT
Base = 2
Significant base digits = 24 (= at least 6 decimal digits)
Arithmetic rounds towards nearest
   Tie breaking rounds to even
Smallest x such that 1.0-base**x != 1.0 = -24
Smallest x such that 1.0-x != 1.0 = 2.98023259e-08
Smallest x such that 1.0+base**x != 1.0 = -23
Smallest x such that 1.0+x != 1.0 = 5.96046519e-08
(Above number + 1.0) - 1.0 = 1.19209290e-07
Number of bits used for exponent = 8
Minimum normalised exponent = -126
Minimum normalised positive number = 1.17549435e-38
The smallest numbers are not kept normalised
Smallest unnormalised positive number = 1.40129846e-45
Float overflow generates a trap
Maximum exponent = 128
Maximum number = 3.40282347e+38
Arithmetic uses a hidden bit
It looks like single length IEEE format

PROPERTIES OF DOUBLE
Base = 2
Significant base digits = 53 (= at least 15 decimal digits)
Arithmetic rounds towards nearest
   Tie breaking rounds to even
Smallest x such that 1.0-base**x != 1.0 = -53
Smallest x such that 1.0-x != 1.0 = 5.5538256285569974e-17
Smallest x such that 1.0+base**x != 1.0 = -52
Smallest x such that 1.0+x != 1.0 = 1.1107651257113995e-16
(Above number + 1.0) - 1.0 = 2.2204460492503131e-16
Number of bits used for exponent = 11
Minimum normalised exponent = -1022
Minimum normalised positive number = 2.2250738585072010e-308

*** WARNING: Possibly bad output from printf above
    expected value around 2.2250738585072010e-308, bit pattern:
    00000000 00000000 00000000 00000000 00000000 00000000 00010000 00000000
    sscanf gave           2.2250738585072010e-308, bit pattern:
    11111111 11111111 11111111 11111111 11111111 11111111 00001111 00000000
    difference= 4.9406564584124659e-324

The smallest numbers are not kept normalised
Smallest unnormalised positive number = 4.9406564584124659e-324
There is an 'infinite' value
Maximum exponent = 1024
Maximum number = 1.7976931348623157e+308
Arithmetic uses a hidden bit
It looks like double length IEEE format

PROPERTIES OF LONG DOUBLE
Base = 2
Significant base digits = 53 (= at least 15 decimal digits)
Arithmetic rounds towards nearest
   Tie breaking rounds to even
Smallest x such that 1.0-base**x != 1.0 = -53
Smallest x such that 1.0-x != 1.0 = 5.5538256285569974e-17
Smallest x such that 1.0+base**x != 1.0 = -52
Smallest x such that 1.0+x != 1.0 = 1.1107651257113995e-16
(Above number + 1.0) - 1.0 = 2.2204460492503131e-16
Number of bits used for exponent = 11
Minimum normalised exponent = -1022
Minimum normalised positive number = 2.2250738585072010e-308

*** WARNING: Possibly bad output from printf above
    expected value around 2.2250738585072010e-308, bit pattern:
    00000000 00000000 00000000 00000000 00000000 00000000 00010000 00000000
    sscanf gave           2.2250738585072010e-308, bit pattern:
    11111111 11111111 11111111 11111111 11111111 11111111 00001111 00000000
    difference= 4.9406564584124659e-324

The smallest numbers are not kept normalised
Smallest unnormalised positive number = 4.9406564584124659e-324
There is an 'infinite' value
Maximum exponent = 1024
Maximum number = 1.7976931348623157e+308
Arithmetic uses a hidden bit
It looks like double length IEEE format

Float expressions are evaluated in a higher precision than double,
   using 64 base digits
Double expressions are evaluated in a higher precision than double,
   using 64 base digits
Long double expressions are evaluated in a higher precision than double,
   using 64 base digits
Memory mallocatable ~= 131008 Kbytes

For hints on dealing with the 2 problems above
   see the section 'TROUBLESHOOTING' in the file enquire.c
% exit
Script done on Sun Jan 10 10:08:30 1993


	Hiroshi Murakami

The patch follows.

*** vfprintf.c.org Sun Jan 10 10:01:50 1993
--- vfprintf.c	Sun Jan 10 09:40:04 1993
***************
*** 239,245 ****
--- 239,249 ----
  #if tahoe
   register /* technically illegal, since we do not know what type va_list is */
  #endif
+ #ifndef ORIGINAL
+ 	_VA_LIST_ ap;
+ #else
  	va_list ap;
+ #endif
  {
  	register char *fmt;	/* format string */
  	register int ch;	/* character from fmt */
***************
*** 748,754 ****
--- 752,762 ----
  	 */
  	for (p = endp - 1; integer; ++expcnt) {
  		tmp = modf(integer / 10, &integer);
+ #ifndef ORIGINAL /* HIROSHI MURAKAMI */
+ 		*p-- = to_char((int)((tmp + .001) * 10));
+ #else
  		*p-- = to_char((int)((tmp + .01) * 10));
+ #endif
  	}
  	switch (fmtch) {
  	case 'f':


END OF THIS MESSAGE.