Nodemcu-firmware: string.format("%.0f")

Created on 19 Jun 2020  路  7Comments  路  Source: nodemcu/nodemcu-firmware

Expected behavior

=("%.0f"):format(3.141)
3

Actual behavior

=("%.0f"):format(3.141)
3.141000

On desktop in Lua 5.1 and 5.3 formatting string %.0f works as expected:

Lua 5.3.1  Copyright (C) 1994-2015 Lua.org, PUC-Rio
> print(("%.0f"):format(3.141))
3

Lua 5.1.5  Copyright (C) 1994-2012 Lua.org, PUC-Rio
> print(("%.0f"):format(3.141))
3

Test code

as above

NodeMCU startup banner

NodeMCU 3.0.0.0 built with Docker provided by frightanic.com
    branch: dev
    commit: 86f3419835b6ed92265f054cf2271795b0757606
    release: 3.0-master_20200610 +7
    release DTS: 202006182133
    SSL: false
    build type: float
    LFS: 0x10000 bytes total capacity
    modules: enduser_setup,file,gpio,net,node,rtcmem,rtctime,sjson,sntp,tmr,uart,wifi
 build 2020-06-19 11:06 powered by Lua 5.1.4 on SDK 3.0.1-dev(fce080e)

Applies also to Lua 5.3.

Hardware

ESP8266 ESP-01

Lua 5.1 Lua 5.3 bug

Most helpful comment

Having stepped through the code with the debugger, the problem is app/libc/stdio.c:L766 if (prec == 0) prec = 6; This version does not differentiate between precision not specified which should default to 6 and an explicit prec=0. This is a bug that dates back to the very earliest versions. Well I've found it. over to one of you guys to propose and test a fix.

All 7 comments

Had same problem some time ago, did not bothered to check on pc version (thought my limited knowledge was the reason), so wen't with math.floor or with 5.3 // when doing division. Just checked example on build 2020-06-19 06:37 powered by Lua 5.3.5 on SDK 3.0.1-dev(fce080e) and got the same problem.

Yep, workaround is quite simple. I think %f uses rounding, so suggested solutions would need to be more sophisticated to replicate the functionality. It would be nice to implement it correctly.

Having stepped through the code with the debugger, the problem is app/libc/stdio.c:L766 if (prec == 0) prec = 6; This version does not differentiate between precision not specified which should default to 6 and an explicit prec=0. This is a bug that dates back to the very earliest versions. Well I've found it. over to one of you guys to propose and test a fix.

Gosh, started to look at it and it was solved like 15 min before :D Just for the record:

if (prec == 0)
        prec = 6;

to

if (!prec)
   {
       prec;
   }

Works also. Used this as reference: Reference

There's is a ++ operator missing in your comment in front of prec.
Anyway it seems that this modification applies to the %g formatting string

/* a precision of 0 is treated as a precision of 1. */

As per comment this is probably not the right fix for the %f.

@KT819GM @vsky279 You guys have a ping-pong and ring the bell when you've got a solution. :+1: to you both. Thanks

There's is a ++ operator missing in your comment in front of prec.
Anyway it seems that this modification applies to the %g formatting string

/* a precision of 0 is treated as a precision of 1. */

As per comment this is probably not the right fix for the %f.

Hi, yes, ++ is missing, for a reason - 1. and 1. I've tested only one string from your example

for i=0,8 do print(("%."..i.."f"):format(pi)) end

and both variants return:

3
3.1
3.14
3.142
3.1416
3.14159
3.141593
3.1415927
3.14159274

BUT, it does not mean that it's same in all situations and I suspect that you've tested your solution far better than me, so I see it as correct bugfix.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

marcelstoer picture marcelstoer  路  4Comments

dicer picture dicer  路  6Comments

ShAzmoodeh picture ShAzmoodeh  路  6Comments

joysfera picture joysfera  路  5Comments

riteshRcH picture riteshRcH  路  3Comments