unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#47302: 27.1; calc math-format-number formatting for floats without decimals is unusual
@ 2021-03-21 21:54 Jelle Licht
  2021-04-21 15:16 ` Stefan Kangas
  0 siblings, 1 reply; 8+ messages in thread
From: Jelle Licht @ 2021-03-21 21:54 UTC (permalink / raw)
  To: 47302

[-- Attachment #1: Type: text/plain, Size: 618 bytes --]

Hey folks,

I run into the following behaviour when using calc in Emacs 27.1 (using
`emacs -Q'):

--8<---------------cut here---------------start------------->8---
(calc-eval "123.0") ; => "123."
(calc-eval "0.0") ; => "0."
--8<---------------cut here---------------end--------------->8---

I would expect this output to be either "123.0" or "123" and "0.0" or
"0" respectively.

I have attached a super simple patch that fixes this issue for me, but I
am not actually certain of the following:

- Was this formatting quirk perhaps there with a purpose? 
- Does my 'fix' have unintended consequences?

Thanks,
 Jelle


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-calc-Fix-formatting-of-floats-without-decimals.patch --]
[-- Type: text/x-patch, Size: 990 bytes --]

From 88e52b073510c86b582487a65fa8ddf52a48e7dd Mon Sep 17 00:00:00 2001
From: Jelle Licht <jlicht@fsfe.org>
Date: Sun, 21 Mar 2021 22:39:41 +0100
Subject: [PATCH] (calc): Fix formatting of floats without decimals

* lisp/calc/calc.el (math-format-number): Fix formatting for floats
  without decimals.
---
 lisp/calc/calc.el | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/lisp/calc/calc.el b/lisp/calc/calc.el
index ec09abb34c..fac9f70915 100644
--- a/lisp/calc/calc.el
+++ b/lisp/calc/calc.el
@@ -3193,8 +3193,9 @@ math-format-number
 		   ((= dpos 0)
 		    (setq str (concat "0" point str)))
 		   ((and (<= exp 0) (> dpos 0))
-		    (setq str (concat (substring str 0 dpos) point
-				      (substring str dpos))))
+                    (when (> len dpos)
+		      (setq str (concat (substring str 0 dpos) point
+				        (substring str dpos)))))
 		   ((> exp 0)
 		    (setq str (concat str (make-string exp ?0) point)))
 		   (t   ; (< dpos 0)
-- 
2.31.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* bug#47302: 27.1; calc math-format-number formatting for floats without decimals is unusual
  2021-03-21 21:54 bug#47302: 27.1; calc math-format-number formatting for floats without decimals is unusual Jelle Licht
@ 2021-04-21 15:16 ` Stefan Kangas
  2021-04-22 13:44   ` Mattias Engdegård
  0 siblings, 1 reply; 8+ messages in thread
From: Stefan Kangas @ 2021-04-21 15:16 UTC (permalink / raw)
  To: Jelle Licht; +Cc: Mattias Engdegård, 47302, David Gillespie

Jelle Licht <jlicht@fsfe.org> writes:

> Hey folks,
>
> I run into the following behaviour when using calc in Emacs 27.1 (using
> `emacs -Q'):
>
> (calc-eval "123.0") ; => "123."
> (calc-eval "0.0") ; => "0."
>
> I would expect this output to be either "123.0" or "123" and "0.0" or
> "0" respectively.
>
> I have attached a super simple patch that fixes this issue for me, but I
> am not actually certain of the following:
>
> - Was this formatting quirk perhaps there with a purpose?
> - Does my 'fix' have unintended consequences?

Copying in Mattias Engdegård in the hope that he can provide some
insight here.

I also put David Gillespie on Cc.

>
> Thanks,
>  Jelle
>
>>From 88e52b073510c86b582487a65fa8ddf52a48e7dd Mon Sep 17 00:00:00 2001
> From: Jelle Licht <jlicht@fsfe.org>
> Date: Sun, 21 Mar 2021 22:39:41 +0100
> Subject: [PATCH] (calc): Fix formatting of floats without decimals
>
> * lisp/calc/calc.el (math-format-number): Fix formatting for floats
>   without decimals.
> ---
>  lisp/calc/calc.el | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/lisp/calc/calc.el b/lisp/calc/calc.el
> index ec09abb34c..fac9f70915 100644
> --- a/lisp/calc/calc.el
> +++ b/lisp/calc/calc.el
> @@ -3193,8 +3193,9 @@ math-format-number
>  		   ((= dpos 0)
>  		    (setq str (concat "0" point str)))
>  		   ((and (<= exp 0) (> dpos 0))
> -		    (setq str (concat (substring str 0 dpos) point
> -				      (substring str dpos))))
> +                    (when (> len dpos)
> +		      (setq str (concat (substring str 0 dpos) point
> +				        (substring str dpos)))))
>  		   ((> exp 0)
>  		    (setq str (concat str (make-string exp ?0) point)))
>  		   (t   ; (< dpos 0)





^ permalink raw reply	[flat|nested] 8+ messages in thread

* bug#47302: 27.1; calc math-format-number formatting for floats without decimals is unusual
  2021-04-21 15:16 ` Stefan Kangas
@ 2021-04-22 13:44   ` Mattias Engdegård
  2021-04-22 15:03     ` Jelle Licht
  0 siblings, 1 reply; 8+ messages in thread
From: Mattias Engdegård @ 2021-04-22 13:44 UTC (permalink / raw)
  To: Stefan Kangas; +Cc: David Gillespie, Jelle Licht, 47302

21 apr. 2021 kl. 17.16 skrev Stefan Kangas <stefan@marxist.se>:
> 
> Jelle Licht <jlicht@fsfe.org> writes:

>> (calc-eval "123.0") ; => "123."
>> (calc-eval "0.0") ; => "0."
>> 
>> I would expect this output to be either "123.0" or "123" and "0.0" or
>> "0" respectively.

Jelle, thanks for the report!

Calc distinguishes integers from floating-point numbers by the presence of a decimal point, so removing it is probably not a good idea. The lack of a trailing 0 after the decimal point is clearly intended but mainly a cosmetic issue; it's uncommon in hand-writing but not in computerese.

We could put a 0 after the decimal point but not doing so saves some space in the often narrow Calc windows. I'd suggest leaving it as it is. The notation is distinctive enough that there is no serious risk of misunderstanding.

If you disagree, do say.






^ permalink raw reply	[flat|nested] 8+ messages in thread

* bug#47302: 27.1; calc math-format-number formatting for floats without decimals is unusual
  2021-04-22 13:44   ` Mattias Engdegård
@ 2021-04-22 15:03     ` Jelle Licht
  2021-04-22 16:35       ` Dave Gillespie
  0 siblings, 1 reply; 8+ messages in thread
From: Jelle Licht @ 2021-04-22 15:03 UTC (permalink / raw)
  To: Mattias Engdegård, Stefan Kangas; +Cc: David Gillespie, 47302

Mattias Engdegård <mattiase@acm.org> writes:

> 21 apr. 2021 kl. 17.16 skrev Stefan Kangas <stefan@marxist.se>:
>> 
>> Jelle Licht <jlicht@fsfe.org> writes:
>
>>> (calc-eval "123.0") ; => "123."
>>> (calc-eval "0.0") ; => "0."
>>> 
>>> I would expect this output to be either "123.0" or "123" and "0.0" or
>>> "0" respectively.
>
> Jelle, thanks for the report!
>
> Calc distinguishes integers from floating-point numbers by the presence of a decimal point, so removing it is probably not a good idea. The lack of a trailing 0 after the decimal point is clearly intended but mainly a cosmetic issue; it's uncommon in hand-writing but not in computerese.
>
> We could put a 0 after the decimal point but not doing so saves some space in the often narrow Calc windows. I'd suggest leaving it as it is. The notation is distinctive enough that there is no serious risk of misunderstanding.
>
> If you disagree, do say.
Hi Mattias,

It would be nice to have a (formatting) option to print 'full'
floating-point numbers. There are a lot of other knobs to tweak
w.r.t. printing numbers, so in that sense it does not seem totally
inconceivable for such a thing to exist.

The context in which I would use this is one where the output of calc is
being used by other programs and data formats (e.g. JSON). For now, I'll
just have to have emacs read and then subsequently print the result of
my calc-adventures, which works fine.

Thanks for the consideration,
 - Jelle





^ permalink raw reply	[flat|nested] 8+ messages in thread

* bug#47302: 27.1; calc math-format-number formatting for floats without decimals is unusual
  2021-04-22 15:03     ` Jelle Licht
@ 2021-04-22 16:35       ` Dave Gillespie
  2021-04-25 15:53         ` Mattias Engdegård
  0 siblings, 1 reply; 8+ messages in thread
From: Dave Gillespie @ 2021-04-22 16:35 UTC (permalink / raw)
  To: Jelle Licht, Mattias Engdegård, Stefan Kangas; +Cc: 47302@debbugs.gnu.org

Wow, it has been a long time since I got any correspondence on Calc!

Yes, I used the notation "123." versus "123.0" with the goal to keep the output concise for casual interactive users.  I agree with Mattias that it is best to leave the default as it is.

Calc has a C language mode ('d C' keystroke, controlled by calc-language).  It is a good point that C mode (and probably others like it) should format integer-valued floats as "123.0" even if the default mode does not.  If we apply Jelle's patch, I suggest making it conditional on calc-language so that it applies only in modes such as C mode.  Or perhaps rework it as a text transformation using calc-language-filter.

You could even create a JSON language mode, but most likely the basic C mode is close enough to serve that purpose.

Thanks!

                                                                -- Dave



-----Original Message-----
From: Jelle Licht <jlicht@fsfe.org> 
Sent: Thursday, April 22, 2021 8:04 AM
To: Mattias Engdegård <mattiase@acm.org>; Stefan Kangas <stefan@marxist.se>
Cc: 47302@debbugs.gnu.org; Dave Gillespie <Daveg@synaptics.com>
Subject: Re: bug#47302: 27.1; calc math-format-number formatting for floats without decimals is unusual

CAUTION: Email originated externally, do not click links or open attachments unless you recognize the sender and know the content is safe.


Mattias Engdegård <mattiase@acm.org> writes:

> 21 apr. 2021 kl. 17.16 skrev Stefan Kangas <stefan@marxist.se>:
>>
>> Jelle Licht <jlicht@fsfe.org> writes:
>
>>> (calc-eval "123.0") ; => "123."
>>> (calc-eval "0.0") ; => "0."
>>>
>>> I would expect this output to be either "123.0" or "123" and "0.0" or
>>> "0" respectively.
>
> Jelle, thanks for the report!
>
> Calc distinguishes integers from floating-point numbers by the presence of a decimal point, so removing it is probably not a good idea. The lack of a trailing 0 after the decimal point is clearly intended but mainly a cosmetic issue; it's uncommon in hand-writing but not in computerese.
>
> We could put a 0 after the decimal point but not doing so saves some space in the often narrow Calc windows. I'd suggest leaving it as it is. The notation is distinctive enough that there is no serious risk of misunderstanding.
>
> If you disagree, do say.
Hi Mattias,

It would be nice to have a (formatting) option to print 'full'
floating-point numbers. There are a lot of other knobs to tweak
w.r.t. printing numbers, so in that sense it does not seem totally
inconceivable for such a thing to exist.

The context in which I would use this is one where the output of calc is
being used by other programs and data formats (e.g. JSON). For now, I'll
just have to have emacs read and then subsequently print the result of
my calc-adventures, which works fine.

Thanks for the consideration,
 - Jelle

^ permalink raw reply	[flat|nested] 8+ messages in thread

* bug#47302: 27.1; calc math-format-number formatting for floats without decimals is unusual
  2021-04-22 16:35       ` Dave Gillespie
@ 2021-04-25 15:53         ` Mattias Engdegård
  2021-04-26 14:58           ` Dave Gillespie
  0 siblings, 1 reply; 8+ messages in thread
From: Mattias Engdegård @ 2021-04-25 15:53 UTC (permalink / raw)
  To: Dave Gillespie; +Cc: Jelle Licht, Stefan Kangas, 47302@debbugs.gnu.org

[-- Attachment #1: Type: text/plain, Size: 1685 bytes --]

22 apr. 2021 kl. 18.35 skrev Dave Gillespie <Daveg@synaptics.com>:

> Wow, it has been a long time since I got any correspondence on Calc!

Good to hear from you, Dave! I just fix the occasional Calc bug now and then.

> Calc has a C language mode ('d C' keystroke, controlled by calc-language).  It is a good point that C mode (and probably others like it) should format integer-valued floats as "123.0" even if the default mode does not.  If we apply Jelle's patch, I suggest making it conditional on calc-language so that it applies only in modes such as C mode.  Or perhaps rework it as a text transformation using calc-language-filter.
> 
> You could even create a JSON language mode, but most likely the basic C mode is close enough to serve that purpose.

These are all good suggestions. Most languages permit trailing decimal points; the only common exceptions that I can think of are Haskell, Ada and Swift. Apparently JSON is also one. Tying the float-format display to the C, Pascal (etc) modes seems a bit incongruous as it has nothing to do with the syntax of those languages.

How to display a floating-point number with zero fraction also depends on what the user wants to do with the result, so there is a good argument for letting him or her do the required post-processing. Sometimes '1.' should become '1.0', sometimes '1'. For instance, in a LaTeX document it would depend on how the author wants to represent significant digits. A JSON parser (such as the one in Emacs) will parse '1.0' and '1' differently, as a float or integer respectively.

I wrote the patch below as a possible solution but in the light of the above, perhaps it's not ideal?


[-- Attachment #2: calc-digit-after-point.diff --]
[-- Type: application/octet-stream, Size: 3710 bytes --]

diff --git a/lisp/calc/calc.el b/lisp/calc/calc.el
index ec09abb34c..1e7d5e7766 100644
--- a/lisp/calc/calc.el
+++ b/lisp/calc/calc.el
@@ -483,6 +483,11 @@ calc-display-sci-low
   "Floating-point numbers with this negative exponent or lower are displayed
 scientific notation in calc-mode.")
 
+(defvar calc-digit-after-point nil
+  "If t, display at least one digit after the decimal point, as in `12.0'.
+If nil, the decimal point may come last in a number, as in `12.'.
+This setting only applies to floats in normal display mode.")
+
 (defvar calc-other-modes nil
   "List of used-defined strings to append to Calculator mode line.")
 
@@ -3184,7 +3189,8 @@ math-format-number
 		      exp (- exp adj)))))
 	  (setq str (int-to-string mant))
 	  (let* ((len (length str))
-		 (dpos (+ exp len)))
+		 (dpos (+ exp len))
+                 (trailing-0 (and calc-digit-after-point "0")))
 	    (if (and (eq fmt 'float)
 		     (<= dpos (+ calc-internal-prec calc-display-sci-high))
 		     (>= dpos (+ calc-display-sci-low 2)))
@@ -3194,9 +3200,11 @@ math-format-number
 		    (setq str (concat "0" point str)))
 		   ((and (<= exp 0) (> dpos 0))
 		    (setq str (concat (substring str 0 dpos) point
-				      (substring str dpos))))
+				      (substring str dpos)
+                                      (and (>= dpos len) trailing-0))))
 		   ((> exp 0)
-		    (setq str (concat str (make-string exp ?0) point)))
+		    (setq str (concat str (make-string exp ?0)
+                                      point trailing-0)))
 		   (t   ; (< dpos 0)
 		    (setq str (concat "0" point
 				      (make-string (- dpos) ?0) str))))
diff --git a/test/lisp/calc/calc-tests.el b/test/lisp/calc/calc-tests.el
index c5aa5a31eb..06010dd417 100644
--- a/test/lisp/calc/calc-tests.el
+++ b/test/lisp/calc/calc-tests.el
@@ -191,6 +191,33 @@ calc-format-radix
     (let ((calc-number-radix 36))
       (should (equal (math-format-number 12345678901) "36#5,O6A,QT1")))))
 
+(ert-deftest calc-display-digit-after-point ()
+  "Test display of trailing 0 after decimal point (bug#47302)."
+  (let ((calc-display-digit-after-point nil))
+    ;; Integral floats have no digits after the decimal point (default).
+    (should (equal (math-format-number '(float 0 0)) "0."))
+    (should (equal (math-format-number '(float 5 0)) "5."))
+    (should (equal (math-format-number '(float 3 1)) "30."))
+    (should (equal (math-format-number '(float 23 0)) "23."))
+    (should (equal (math-format-number '(float 123 0)) "123."))
+    (should (equal (math-format-number '(float 1 -1)) "0.1"))
+    (should (equal (math-format-number '(float 54 -1)) "5.4"))
+    (should (equal (math-format-number '(float 1 -4)) "1e-4"))
+    (should (equal (math-format-number '(float 1 14)) "1e14"))
+    (should (equal (math-format-number 12) "12")))
+  (let ((calc-display-digit-after-point t))
+    ;; Integral floats have at least one digit after the decimal point.
+    (should (equal (math-format-number '(float 0 0)) "0.0"))
+    (should (equal (math-format-number '(float 5 0)) "5.0"))
+    (should (equal (math-format-number '(float 3 1)) "30.0"))
+    (should (equal (math-format-number '(float 23 0)) "23.0"))
+    (should (equal (math-format-number '(float 123 0)) "123.0"))
+    (should (equal (math-format-number '(float 1 -1)) "0.1"))
+    (should (equal (math-format-number '(float 54 -1)) "5.4"))
+    (should (equal (math-format-number '(float 1 -4)) "1e-4"))
+    (should (equal (math-format-number '(float 1 14)) "1e14"))
+    (should (equal (math-format-number 12) "12"))))
+
 (ert-deftest calc-calendar ()
   "Test calendar conversions (bug#36822)."
   (should (equal (calcFunc-julian (math-parse-date "2019-07-27")) 2458692))

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* bug#47302: 27.1; calc math-format-number formatting for floats without decimals is unusual
  2021-04-25 15:53         ` Mattias Engdegård
@ 2021-04-26 14:58           ` Dave Gillespie
  2021-04-27 16:15             ` Mattias Engdegård
  0 siblings, 1 reply; 8+ messages in thread
From: Dave Gillespie @ 2021-04-26 14:58 UTC (permalink / raw)
  To: Mattias Engdegård; +Cc: Jelle Licht, Stefan Kangas, 47302@debbugs.gnu.org

Yes, that patch makes sense.  Thanks, and thanks for helping with this old beast!

                                                                -- Dave



-----Original Message-----
From: Mattias Engdegård <mattiase@acm.org> 
Sent: Sunday, April 25, 2021 8:54 AM
To: Dave Gillespie <Daveg@synaptics.com>
Cc: Jelle Licht <jlicht@fsfe.org>; Stefan Kangas <stefan@marxist.se>; 47302@debbugs.gnu.org
Subject: Re: bug#47302: 27.1; calc math-format-number formatting for floats without decimals is unusual

CAUTION: Email originated externally, do not click links or open attachments unless you recognize the sender and know the content is safe.


22 apr. 2021 kl. 18.35 skrev Dave Gillespie <Daveg@synaptics.com>:

> Wow, it has been a long time since I got any correspondence on Calc!

Good to hear from you, Dave! I just fix the occasional Calc bug now and then.

> Calc has a C language mode ('d C' keystroke, controlled by calc-language).  It is a good point that C mode (and probably others like it) should format integer-valued floats as "123.0" even if the default mode does not.  If we apply Jelle's patch, I suggest making it conditional on calc-language so that it applies only in modes such as C mode.  Or perhaps rework it as a text transformation using calc-language-filter.
>
> You could even create a JSON language mode, but most likely the basic C mode is close enough to serve that purpose.

These are all good suggestions. Most languages permit trailing decimal points; the only common exceptions that I can think of are Haskell, Ada and Swift. Apparently JSON is also one. Tying the float-format display to the C, Pascal (etc) modes seems a bit incongruous as it has nothing to do with the syntax of those languages.

How to display a floating-point number with zero fraction also depends on what the user wants to do with the result, so there is a good argument for letting him or her do the required post-processing. Sometimes '1.' should become '1.0', sometimes '1'. For instance, in a LaTeX document it would depend on how the author wants to represent significant digits. A JSON parser (such as the one in Emacs) will parse '1.0' and '1' differently, as a float or integer respectively.

I wrote the patch below as a possible solution but in the light of the above, perhaps it's not ideal?






^ permalink raw reply	[flat|nested] 8+ messages in thread

* bug#47302: 27.1; calc math-format-number formatting for floats without decimals is unusual
  2021-04-26 14:58           ` Dave Gillespie
@ 2021-04-27 16:15             ` Mattias Engdegård
  0 siblings, 0 replies; 8+ messages in thread
From: Mattias Engdegård @ 2021-04-27 16:15 UTC (permalink / raw)
  To: Dave Gillespie; +Cc: 47302-done, Jelle Licht, Stefan Kangas

26 apr. 2021 kl. 16.58 skrev Dave Gillespie <Daveg@synaptics.com>:
> 
> Yes, that patch makes sense.

Good, patch pushed as-is. It can be tweaked later on if needed. Jelle, hope this helps.

>  Thanks, and thanks for helping with this old beast!

Happy to give a hand. Nowhere else in Emacs -- and I mean this in the best possible way -- do I get a feeling of Mad Science as strongly as when dealing with Calc. "Surely Calc doesn't attempt to do this... oh yes. Yes it does."






^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2021-04-27 16:15 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-21 21:54 bug#47302: 27.1; calc math-format-number formatting for floats without decimals is unusual Jelle Licht
2021-04-21 15:16 ` Stefan Kangas
2021-04-22 13:44   ` Mattias Engdegård
2021-04-22 15:03     ` Jelle Licht
2021-04-22 16:35       ` Dave Gillespie
2021-04-25 15:53         ` Mattias Engdegård
2021-04-26 14:58           ` Dave Gillespie
2021-04-27 16:15             ` Mattias Engdegård

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).