Raymond Toy pushed to branch rtoy-print-using-ryu at cmucl / cmucl

Commits:

2 changed files:

Changes:

  • src/code/ryu-print.lisp
    ... ... @@ -497,48 +497,65 @@
    497 497
                                         nil))))))))))))
    
    498 498
     
    
    499 499
     ;;; Ryu ~F
    
    500
    +(defun emit-fixed (stream rounded is-negative-p w
    
    501
    +		   overflowchar padchar at-sign-p
    
    502
    +		   force-trailing-zero-p value-is-nonzero-p)
    
    503
    +  "Write a d2fixed result ROUNDED right-justified in W with the usual
    
    504
    +   ~F padding and overflow rules.  FORCE-TRAILING-ZERO-P appends a
    
    505
    +   single \"0\" after the dot when no fractional digits remain.
    
    506
    +   VALUE-IS-NONZERO-P enables the leading-\"0\" drop when the field
    
    507
    +   would otherwise overflow W."
    
    508
    +  (declare (type simple-string rounded))
    
    509
    +  (let* ((len           (length rounded))
    
    510
    +	 (dot           (position #\. rounded))
    
    511
    +	 (int-end       (or dot len))
    
    512
    +	 (frac-start    (if dot (1+ dot) len))
    
    513
    +	 (frac-len      (- len frac-start))
    
    514
    +	 (frac-out-len  (cond ((plusp frac-len) frac-len)
    
    515
    +			      (force-trailing-zero-p 1)
    
    516
    +			      (t 0)))
    
    517
    +	 (sign-len      (if (or is-negative-p at-sign-p) 1 0))
    
    518
    +	 ;; CLHS 22.3.3.1: the leading "0" before the dot is optional
    
    519
    +	 ;; when the magnitude is < 1 (integer part is exactly "0")
    
    520
    +	 ;; and the original value is nonzero.  Require something to be
    
    521
    +	 ;; written after the dot so we never drop down to just ".".
    
    522
    +	 (leading-zero-droppable
    
    523
    +	   (and (= int-end 1)
    
    524
    +		(char= (char rounded 0) #\0)
    
    525
    +		value-is-nonzero-p
    
    526
    +		(plusp frac-out-len)))
    
    527
    +	 (full-len  (+ sign-len int-end 1 frac-out-len))
    
    528
    +	 (drop-leading-zero-p
    
    529
    +	   (and leading-zero-droppable w (> full-len w)))
    
    530
    +	 (field-len (if drop-leading-zero-p (1- full-len) full-len)))
    
    531
    +    (flet ((write-field ()
    
    532
    +	     (cond (is-negative-p (write-char #\- stream))
    
    533
    +		   (at-sign-p     (write-char #\+ stream)))
    
    534
    +	     (unless drop-leading-zero-p
    
    535
    +	       (write-string rounded stream :start 0 :end int-end))
    
    536
    +	     (write-char #\. stream)
    
    537
    +	     (cond ((plusp frac-len)
    
    538
    +		    (write-string rounded stream :start frac-start :end len))
    
    539
    +		   (force-trailing-zero-p
    
    540
    +		    (write-char #\0 stream)))))
    
    541
    +      (declare (dynamic-extent #'write-field))
    
    542
    +      (pad-overflow stream field-len w overflowchar padchar #'write-field))))
    
    543
    +
    
    500 544
     (defun format-f-fixed (stream value w d
    
    501 545
                            overflowchar padchar at-sign-p)
    
    502
    -  "Write the ~F representation of VALUE rounded to D digits after the
    
    503
    -  decimal point, right-justified in a field of width W."
    
    504
    -  (declare (type (or single-float double-float) value))
    
    546
    +  "Write the ~F representation of VALUE rounded to exactly D digits
    
    547
    +   after the decimal point, right-justified in a field of width W.
    
    548
    +   This is the explicit-D path: no \"single zero\" rule applies, so
    
    549
    +   D=0 yields \"d.\" with nothing after the dot.  The optional
    
    550
    +   leading zero before the decimal point is dropped when keeping it
    
    551
    +   would overflow W (CLHS 22.3.3.1; FORMAT.F.13)."
    
    552
    +  (declare (type (or single-float double-float) value)
    
    553
    +	   (type (integer 0 *) d))
    
    505 554
       (multiple-value-bind (is-negative-p abs-value)
    
    506 555
           (get-sign-and-absolute-value value)
    
    507
    -    (let* ((raw-string (d2fixed abs-value d))
    
    508
    -           (raw-len    (length raw-string))
    
    509
    -           (sign-len   (if (or is-negative-p at-sign-p) 1 0))
    
    510
    -           (need-dot   (zerop d))
    
    511
    -	   (full-field-len (+ sign-len raw-len (if need-dot 1 0)))
    
    512
    -	   ;; CLHS 22.3.3.1: the leading zero before the decimal point
    
    513
    -	   ;; is optional when the magnitude is nonzero and less than 1.
    
    514
    -	   ;; d2fixed always emits it (e.g. "0.50" for 0.5), so detect
    
    515
    -	   ;; that case here and drop the zero if the field would not
    
    516
    -	   ;; otherwise fit in W.  For exact zero the leading digit is
    
    517
    -	   ;; required, so PLUSP ABS-VALUE gates the dropping.
    
    518
    -	   (leading-zero-droppable
    
    519
    -	     (and (plusp abs-value)
    
    520
    -		  (>= raw-len 2)
    
    521
    -		  (char= (char raw-string 0) #\0)
    
    522
    -		  (char= (char raw-string 1) #\.)))
    
    523
    -	   ;; Drop the leading zero if we it's droppable and W is
    
    524
    -	   ;; given and the number won't fit in width W field.
    
    525
    -	   (drop-leading-zero-p
    
    526
    -	     (and leading-zero-droppable
    
    527
    -		  w
    
    528
    -		  (> full-field-len w)))
    
    529
    -           (field-len (if drop-leading-zero-p
    
    530
    -			  (1- full-field-len)
    
    531
    -			  full-field-len)))
    
    532
    -      (flet ((write-field ()
    
    533
    -               (cond (is-negative-p (write-char #\- stream))
    
    534
    -                     (at-sign-p     (write-char #\+ stream)))
    
    535
    -	       (cond (drop-leading-zero-p
    
    536
    -		      (write-string raw-string stream :start 1))
    
    537
    -		     (t
    
    538
    -		      (write-string raw-string stream)))
    
    539
    -               (when need-dot (write-char #\. stream))))
    
    540
    -	(declare (dynamic-extent #'write-field))
    
    541
    -	(pad-overflow stream field-len w overflowchar padchar #'write-field)))))
    
    556
    +    (emit-fixed stream (d2fixed abs-value d) is-negative-p w
    
    557
    +		overflowchar padchar at-sign-p nil
    
    558
    +		(plusp abs-value))))
    
    542 559
     
    
    543 560
     (defun reshape-fixed-length (digit-count exponent)
    
    544 561
       ;; DIGIT-COUNT is the number of digits returned by d2s/f2s.  That no
    
    ... ... @@ -583,62 +600,11 @@
    583 600
           (declare (dynamic-extent #'write-field))
    
    584 601
           (pad-overflow stream field-len w overflowchar padchar #'write-field))))
    
    585 602
     	 
    
    586
    -(defun emit-rounded-to-width (stream value frac is-negative-p w
    
    587
    -			      overflowchar padchar at-sign-p)
    
    588
    -  "Round (the magnitude of) VALUE to FRAC fractional digits with
    
    589
    -   d2fixed and write it right-justified in a field of width W.  At
    
    590
    -   least one fractional digit is always shown: if FRAC is 0 the
    
    591
    -   rounded value is integral and a single \"0\" is appended after the
    
    592
    -   decimal point (CLHS 22.3.3.1).  The leading zero before the
    
    593
    -   decimal point is kept when the field fits in W (FORMAT.F.47) and
    
    594
    -   dropped when keeping it would overflow W (FORMAT.F.46).  Used by
    
    595
    -   the free-format ~F path when the shortest representation does not
    
    596
    -   fit in W."
    
    597
    -  (declare (type (or single-float double-float) value)
    
    598
    -	   (type (integer 0 *) frac))
    
    599
    -  (let* ((rounded   (d2fixed (float (abs value) 1d0) frac))
    
    600
    -	 (len       (length rounded))
    
    601
    -	 ;; ROUNDED is "ddd" (frac=0) or "ddd.ddd" (frac>0).  Locate the
    
    602
    -	 ;; decimal point and the integer/fractional digit spans without
    
    603
    -	 ;; allocating substrings.
    
    604
    -	 (dot        (position #\. rounded))
    
    605
    -	 (int-end    (or dot len))
    
    606
    -	 (frac-start (if dot (1+ dot) len))
    
    607
    -	 (frac-len   (- len frac-start))
    
    608
    -	 ;; At least one fractional digit is always shown; when there are
    
    609
    -	 ;; none a single "0" is emitted instead.
    
    610
    -	 (frac-out-len (max 1 frac-len))
    
    611
    -	 (sign-len   (if (or is-negative-p at-sign-p) 1 0))
    
    612
    -	 ;; The leading "0." may be shortened to "." when the magnitude
    
    613
    -	 ;; is < 1 (integer part is the single digit "0") and nonzero,
    
    614
    -	 ;; and only when the full field would not fit in W.
    
    615
    -	 (leading-zero-droppable
    
    616
    -	   (and (= int-end 1)
    
    617
    -		(char= (char rounded 0) #\0)
    
    618
    -		(not (zerop value))))
    
    619
    -	 (full-len   (+ sign-len int-end 1 frac-out-len))
    
    620
    -	 (drop-leading-zero-p
    
    621
    -	   (and leading-zero-droppable w (> full-len w)))
    
    622
    -	 (field-len  (if drop-leading-zero-p (1- full-len) full-len)))
    
    623
    -    (flet ((write-field ()
    
    624
    -	     (cond (is-negative-p (write-char #\- stream))
    
    625
    -		   (at-sign-p     (write-char #\+ stream)))
    
    626
    -	     (unless drop-leading-zero-p
    
    627
    -	       (write-string rounded stream :start 0 :end int-end))
    
    628
    -	     (write-char #\. stream)
    
    629
    -	     (cond ((zerop frac-len)
    
    630
    -		    (write-char #\0 stream))
    
    631
    -		   (t
    
    632
    -		    (write-string rounded stream :start frac-start :end len)))))
    
    633
    -      (declare (dynamic-extent #'write-field))
    
    634
    -      (pad-overflow stream field-len w overflowchar padchar #'write-field))))
    
    635
    -
    
    636 603
     (defun format-f-free (stream value w
    
    637 604
                           overflowchar padchar at-sign-p)
    
    638 605
       (declare (type (or single-float double-float) value))
    
    639 606
       (multiple-value-bind (is-negative-p abs-value)
    
    640 607
           (get-sign-and-absolute-value value)
    
    641
    -    (declare (ignore abs-value))
    
    642 608
         (multiple-value-bind (mantissa exponent)
    
    643 609
     	(parsed-exp-form (float-to-string value))
    
    644 610
           (let* ((digit-count (mantissa-digit-count mantissa))
    
    ... ... @@ -658,16 +624,15 @@
    658 624
     	   (loop repeat w
    
    659 625
     		 do (write-char overflowchar stream)))
    
    660 626
     	  (t
    
    661
    -	   ;; The shortest form does not fit in W.  D was not specified,
    
    662
    -	   ;; so round the value to the largest number of fractional
    
    663
    -	   ;; digits D-FIT that fits, then display it.  Per CLHS 22.3.3.1,
    
    664
    -	   ;; if the fraction rounds away to nothing a single zero digit
    
    665
    -	   ;; must still appear after the decimal point.  EMIT-ROUNDED-TO-
    
    666
    -	   ;; WIDTH may drop the leading "0" before the dot if keeping it
    
    667
    -	   ;; would still overflow W.
    
    668
    -	   (emit-rounded-to-width stream value (max 0 d-fit)
    
    669
    -				  is-negative-p w
    
    670
    -				  overflowchar padchar at-sign-p)))))))
    
    627
    +	   ;; The shortest form does not fit in W.  Round to the largest
    
    628
    +	   ;; number of fractional digits D-FIT that fits and emit via
    
    629
    +	   ;; EMIT-FIXED, forcing a trailing "0" if the fraction rounds
    
    630
    +	   ;; away (CLHS 22.3.3.1; FORMAT.F.46 may drop the leading "0"
    
    631
    +	   ;; before the dot if keeping it would still overflow W).
    
    632
    +	   (emit-fixed stream
    
    633
    +		       (d2fixed abs-value (max 0 d-fit))
    
    634
    +		       is-negative-p w overflowchar padchar at-sign-p
    
    635
    +		       t (plusp abs-value))))))))
    
    671 636
     
    
    672 637
     (defun format-f (stream value w d k overflowchar padchar at-sign-p)
    
    673 638
       (declare (type (or single-float double-float) value)
    

  • src/i18n/locale/cmucl.pot
    No preview for this file type