12
\$\begingroup\$

Goal

Given an input number, round it off to the nearest number with one significant figure.

Requirements

Input

  • A floating point number.
  • Assume the input number results in an output within the data type's limits (ie. ignore overflow errors.)
  • 0 is an invalid input.
  • Numbers that cannot be accurately represented in the floating point data type (eg. "0.35" being stored as 0.3499999) do not have to be supported.

Output

  • The nearest number that consists of one non-zero digit and any number of zero digits.
  • The result must support negative numbers and fractional numbers.
  • When the input lies exactly between two possible outputs, round away from zero.

Presentation

The focus is on the calculation rather than the presentation. The output may be a floating point data type. It may be text either in full or in scientific notation. If you find a loophole where presenting a certain way reduces your byte count, kudos to you!

Examples

9
-3000
.2
0.2
-.2
7e12
5e-15
1e0

Test Cases

Input     Output
1         1
10        10
17        20
99        100
54321     50000
56789     60000
-123      -100
-789      -800
0.23      0.2
0.25      0.3
-0.25     -0.3
4.56e23   5e23
4.56e-23  5e-23

Scoring

The code with the least byte-count after one week wins.

\$\endgroup\$
11
  • 3
    \$\begingroup\$ I think "one significant figure" is the phrase you're looking for. \$\endgroup\$ Commented Jul 20, 2017 at 5:28
  • 2
    \$\begingroup\$ The rounding rule for 0 is pretty weird. \$\endgroup\$
    – xnor
    Commented Jul 20, 2017 at 5:37
  • 2
    \$\begingroup\$ @xnor, you're right. 0 is closer to 0.0001 than 1. I think 0 should simply be invalid. \$\endgroup\$ Commented Jul 20, 2017 at 5:42
  • 1
    \$\begingroup\$ Yeah, and it doesn't match the goal statement. \$\endgroup\$ Commented Jul 20, 2017 at 5:42
  • 2
    \$\begingroup\$ Duplicate of codegolf.stackexchange.com/questions/93547/round-to-n-sig-figs ? \$\endgroup\$
    – Neil
    Commented Jul 20, 2017 at 7:40

12 Answers 12

12
\$\begingroup\$

C# (.NET Core), 19 12 bytes

n=>$"{n:G1}"

Try it online!

Examples:

Input     Output
----------------
 54321     5E+04
-56789    -6E+04
 99        1E+02
 0.23      0.2
 0.25      0.3
-0.25     -0.3
 4.56e23   5E+23
 4.56e-23  5E-23

With the new versions of C# we also got shorter ways to achieve this, as Calculuswhiz wisely noted in the comments.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Shorter way to format: n=>$"{n:G1}" \$\endgroup\$ Commented Jan 13, 2022 at 20:29
9
\$\begingroup\$

Javascript, 19 bytes

x=>x.toPrecision(1)
\$\endgroup\$
9
  • \$\begingroup\$ This doesn’t satisfy the specification on 0 or 25. \$\endgroup\$ Commented Jul 20, 2017 at 5:33
  • \$\begingroup\$ Interesting. The spec for 0 doesn't make sense to me. But the 0.35 thing...looks like Javascript is trying to avoid bias in rounding, but the spec wants the bias. \$\endgroup\$ Commented Jul 20, 2017 at 5:38
  • \$\begingroup\$ Hey, you changed your comment - you wrote 0.35 not 25 before. I think it does satisfy the spec for 25 - it returns "3e+1" which seems right to me. \$\endgroup\$ Commented Jul 20, 2017 at 5:41
  • \$\begingroup\$ Sorry, I changed it from 0.35 because 0.35 has no exact floating-point representation. The behavior must be browser-dependent; I get 252e+1 in Firefox. \$\endgroup\$ Commented Jul 20, 2017 at 5:45
  • \$\begingroup\$ Yup, I get those two different results in Chrome vs Firefox. Wow. \$\endgroup\$ Commented Jul 20, 2017 at 5:47
6
\$\begingroup\$

MATL, 3 bytes

1&V

Try it online! Or verify all test cases.

Test case 0.25 fails for the compiler running in Octave on TIO, but works in Matlab on Windows:

enter image description here

The different behaviour is caused by Octave's/Matlab's sprintf function using either "banker's rounding" or ".5 away from zero" rounding, depending on platform. More information and tests can be found here.


For 6 bytes,

1t3$Yo

works both on Octave and on Matlab. Verify all test cases.

\$\endgroup\$
2
  • 2
    \$\begingroup\$ "banker's rounding" is pretty much what made me delete my Jelly answer. >_< \$\endgroup\$ Commented Jul 20, 2017 at 16:23
  • \$\begingroup\$ @EriktheOutgolfer Yes, I figured out that was the reason too. I'm lucky that Matlab doesn't do that :-D \$\endgroup\$
    – Luis Mendo
    Commented Jul 20, 2017 at 16:37
4
\$\begingroup\$

Retina, 63 62 bytes

1`[1-9]
$*#
#\.?[5-9]
#$&
T`d`0`#[\d.]+
0(\.?)#{10}
1$1
#+
$.0

Try it online!

\$\endgroup\$
12
  • \$\begingroup\$ Apparently you don't have to worry about trailing zeros so you can remove the last stage completely (although I'm impressed by it, it's not every day you see three question marks in the space of four characters). \$\endgroup\$
    – Neil
    Commented Jul 20, 2017 at 8:57
  • \$\begingroup\$ Unfortunately this answer appears to fail for 0.99. \$\endgroup\$
    – Neil
    Commented Jul 20, 2017 at 8:59
  • \$\begingroup\$ Also fails for 0.099 etc. My attempt at a fix: Try it online! \$\endgroup\$
    – Neil
    Commented Jul 20, 2017 at 9:06
  • \$\begingroup\$ Also fails for 99.99, 100.001, ... \$\endgroup\$
    – Neil
    Commented Jul 20, 2017 at 9:29
  • \$\begingroup\$ Still wrong for 0.099, sorry. On the bright side I think you can remove the + after the ; on the third line. \$\endgroup\$
    – Neil
    Commented Jul 20, 2017 at 19:06
2
\$\begingroup\$

PHP, 45 bytes

<?=round($x=$argv[1],-floor(log10(abs($x))));

Try it online!

Same method as my python 2 answer.

Also seems to correctly handle 0.35, which puts it a peg above the JS answer too :D

\$\endgroup\$
2
  • \$\begingroup\$ Interestingly, I think your deleted Python 3 answer may work in Python 2. \$\endgroup\$ Commented Jul 20, 2017 at 8:48
  • \$\begingroup\$ Tested, and it does! Edited and undeleted the python answer now \$\endgroup\$
    – Mayube
    Commented Jul 20, 2017 at 8:50
2
\$\begingroup\$

T-SQL, 27 bytes

SELECT FORMAT(i,'G1')FROM t

Using the same .Net formatting code as Carlos Alejo's C# answer. Input is from float column i in pre-existing table t, per our IO standards

Test cases:

Input         Output
------------ --------
1             1
10            1E+01
17            2E+01
99            1E+02
54321         5E+04
56789         6E+04
-123         -1E+02
-789         -8E+02
0.23          0.2
0.25          0.3
-0.25        -0.3
4.56E+23      5E+23
4.56E-23      5E-23

(Pretty handy that I can pre-load the input table with all these values and run them at once.)

\$\endgroup\$
2
\$\begingroup\$

Excel 2016, 36

  • Input A1.
  • A2: =10^INT(LOG10(ABS(A1
  • Result: =A2*ROUND(A1/A2,
\$\endgroup\$
1
\$\begingroup\$

Python 2, 62 bytes

lambda x:round(x,-int(floor(log10(abs(x)))))
from math import*

Try it online!

Not used to python golfing, but this works.

Fails on 0.35 due to floating point inaccuracies.

Thanks to Anders Kaseorg for pointing out that this works correctly in Python 2

\$\endgroup\$
7
  • \$\begingroup\$ The output for 0.25 is supposed to be 0.3. \$\endgroup\$ Commented Jul 20, 2017 at 8:27
  • \$\begingroup\$ @AndersKaseorg I'm not sure why, but I can only assume it's due to the same floating-point inaccuracies as the Javascript answer. \$\endgroup\$
    – Mayube
    Commented Jul 20, 2017 at 8:29
  • \$\begingroup\$ Hmm wait 25 has the same problem... weird. \$\endgroup\$
    – Mayube
    Commented Jul 20, 2017 at 8:29
  • \$\begingroup\$ For anyone wondering, Python 2's round rounds away from zero while Python 3 rounds to even, that's why this works in Py2 but not 3. \$\endgroup\$
    – flornquake
    Commented Jul 20, 2017 at 14:28
  • \$\begingroup\$ you can golf few bytes using log(x,10) instead of log10(abs(x)). \$\endgroup\$ Commented Jul 21, 2017 at 13:26
1
\$\begingroup\$

Guile, 23 bytes

(format #t"~,0e"(read))

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Perl 5, 15 bytes

printf"%.1g",<>

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Zsh, 14 bytes

Port of the perl answer. Try it Online!

printf %.1g $1
\$\endgroup\$
0
\$\begingroup\$

Forth (gforth), 24 bytes

: f 1 set-precision f. ;

Try it online!

Input is expected on the floating point stack. Output is to stdout

I don't like making changes to the global (for this instance) precision of the floating point output functions, but it saves a lot of bytes to not have to restore the previous value at the end. Does not output in engineering or scientific notation, regardless of input.

Note: For some reason, the tio interpreter converts 0.25 to 0.2, while my local installation converts 0.25 to 0.3. I'm not entirely sure why this is, but since I get the correct result locally, I'm leaving my answer as-is

: f                   \ start a new word definition
  1 set-precision     \ set the floating point output words to use 1 significant digit
  f.                  \ output the top of the floating point stack
;                     \ end the word definition
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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