0

That's probably a low hanging fruit.

In short, what I want:

6.7690001 ---> 6.77

I know how to do it in org mode table using regular TBLFM:

|---------|
|6.7690001|
|---------|
#+TBLFM: @1$1=@1$1;%.2f

Moving pointer to the formula line and pressing C-c C-c, results in:

|------|
| 6.77 |
|------|
#[pointer]+TBLFM: @1$1=@1$1;%.2f

The question now is: How to do exactly this using elisp code within the formula line?

|---------|
|6.7690001|
|---------|
#+TBLFM: @1$1='(???<elisp code>???)

Background:

I'm doing a complex calculation with an org mode table, switching formats multiple times within the process. That forces me to use elisp code within the formula line, pushing me out of my comfort zone. While developing the table I've noticed, that sometimes the calculation result is output in a weird format.

For example:

0.5+0.5=1.00000001, instead of 0.5+0.5=1

I'm curious why but have no clue why the output sometimes is like that, but I don't like it - and know how to fix it regularly, as mentioned. But in elisp code? There are just some things, I know to do regularly, but not when using elisp code.

4
  • "Floating point numbers are like sandpiles: every time you move one, you lose a little sand and you pick up a little dirt" (p. 117 of Kernighan and Plauger's "Elements of Programming Style"). And as they also say on p. 116: "10.0 times 0.1 is hardly ever 1.0".
    – NickD
    Commented Jun 14, 2023 at 14:53
  • But in answer to your question: you can say #+TBLFM: @1$1='(/ 1.0 3.0);%.2f. The format specification will be applied to the result, whether the formula is a Calc one or a Lisp one.
    – NickD
    Commented Jun 14, 2023 at 14:55
  • For the floating point "problem", see also emacs.stackexchange.com/questions/44457/floating-point-addition and references therein.
    – NickD
    Commented Jun 14, 2023 at 15:03
  • Did you get to try either or both of the solutions? Did one or both work? Providing feedback (either through comments or, preferably, through upvotes/downvotes and accepting an answer) helps future visitors know whether the question has a good answer. Otherwise, the question (and the answers) is useless to anybody but yourself.
    – NickD
    Commented Jun 17, 2023 at 13:16

2 Answers 2

1

You can use this function

   (defun %.2f(x)
     "..."
     (/(round(*100x))100.0))

   (%.2f 6.7690001) => 6.77

I'm not sure that the choice of the name of my function is so judicious...

4
  • Why wouldn't you use the format as suggested in my comment?
    – NickD
    Commented Jun 14, 2023 at 17:24
  • I assumed the OP wanted pure elisp code.
    – gigiair
    Commented Jun 14, 2023 at 18:12
  • You may be right: we'll have to wait and see I guess.
    – NickD
    Commented Jun 14, 2023 at 19:38
  • Your approach cut it, gave the decisive push to solution. But your syntax threw me off for a couple of days. Adding missing spaces within the formulas made it work: (defun %.2f(x) "..." (/ (round (* 100 x)) 100.0)) . The conventional ;%.2f method, indeed, was applicable, but didn't suffice due to complexity; the formatting part needs to be the last thing in line & #TBLFMs can not be concatenated with :: to 1-liners, leading to a situation, where it doesn't work once you try to add further operations on top of it, like turning "." to a "," or doing that in a 1-liner with 2nd #TBLFM.
    – starquake
    Commented Jun 19, 2023 at 20:45
1

You can say

| 0.33 |
#+TBLFM: @1$1='(/ 1.0 3.0);%.2f

The format specification will be applied to the result, whether the formula is a Calc one or a Lisp one.

See Formula syntax for Lisp where it says:

A formula is evaluated as a Lisp form when it starts with a single-quote followed by an opening parenthesis. Cell table references are interpolated into the Lisp form before execution. The evaluation should return either a string or a number. Evaluation modes and a printf format used to render the returned values can be specified after a semicolon.

[emphasis added]

Not the answer you're looking for? Browse other questions tagged or ask your own question.