11
\$\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\$ Jul 20 '17 at 5:28
  • 2
    \$\begingroup\$ The rounding rule for 0 is pretty weird. \$\endgroup\$
    – xnor
    Jul 20 '17 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\$ Jul 20 '17 at 5:42
  • 1
    \$\begingroup\$ Yeah, and it doesn't match the goal statement. \$\endgroup\$ Jul 20 '17 at 5:42
  • 2
    \$\begingroup\$ Duplicate of codegolf.stackexchange.com/questions/93547/round-to-n-sig-figs ? \$\endgroup\$
    – Neil
    Jul 20 '17 at 7:40

13 Answers 13

11
\$\begingroup\$

C# (.NET Core), 19 bytes

n=>n.ToString("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
\$\endgroup\$
9
\$\begingroup\$

Javascript, 19 bytes

x=>x.toPrecision(1)
\$\endgroup\$
9
  • \$\begingroup\$ This doesn’t satisfy the specification on 0 or 25. \$\endgroup\$ Jul 20 '17 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\$ Jul 20 '17 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\$ Jul 20 '17 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\$ Jul 20 '17 at 5:45
  • \$\begingroup\$ Yup, I get those two different results in Chrome vs Firefox. Wow. \$\endgroup\$ Jul 20 '17 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
  • 1
    \$\begingroup\$ "banker's rounding" is pretty much what made me delete my Jelly answer. >_< \$\endgroup\$ Jul 20 '17 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
    Jul 20 '17 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
    Jul 20 '17 at 8:57
  • \$\begingroup\$ Unfortunately this answer appears to fail for 0.99. \$\endgroup\$
    – Neil
    Jul 20 '17 at 8:59
  • \$\begingroup\$ Also fails for 0.099 etc. My attempt at a fix: Try it online! \$\endgroup\$
    – Neil
    Jul 20 '17 at 9:06
  • \$\begingroup\$ Also fails for 99.99, 100.001, ... \$\endgroup\$
    – Neil
    Jul 20 '17 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
    Jul 20 '17 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\$ Jul 20 '17 at 8:48
  • \$\begingroup\$ Tested, and it does! Edited and undeleted the python answer now \$\endgroup\$
    – Mayube
    Jul 20 '17 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\$
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\$ Jul 20 '17 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
    Jul 20 '17 at 8:29
  • \$\begingroup\$ Hmm wait 25 has the same problem... weird. \$\endgroup\$
    – Mayube
    Jul 20 '17 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
    Jul 20 '17 at 14:28
  • \$\begingroup\$ you can golf few bytes using log(x,10) instead of log10(abs(x)). \$\endgroup\$ Jul 21 '17 at 13:26
1
\$\begingroup\$

Guile, 23 bytes

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

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Excel, 14 bytes

=ROUNDUP(A1,1)
\$\endgroup\$
4
  • \$\begingroup\$ Welcome to the site! This is a nice first answer, do you have any links to somewhere this can be tested, preferably online, so that other users don't have to download Excel? \$\endgroup\$ Sep 5 '19 at 14:09
  • \$\begingroup\$ Unfortunately I don't think there are any free Microsoft sites due to licensing, sorry. I've seen other Excel answers on Code Golf but I'm not sure how those are validated since I'm new! \$\endgroup\$
    – rew
    Sep 5 '19 at 14:17
  • 1
    \$\begingroup\$ That doesn't work for most of the test cases. It's rounding up to the "tenths" position. It needs to round off (not up) to whatever the most significant position is. \$\endgroup\$ Sep 10 '19 at 0:26
  • \$\begingroup\$ Microsoft has a Google Sheets like service for Excel. \$\endgroup\$ Aug 8 '20 at 3:24
1
\$\begingroup\$

Excel 2016, 36

  • Input A1.
  • A2: =10^INT(LOG10(ABS(A1
  • Result: =A2*ROUND(A1/A2,
\$\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, privacy policy and cookie policy

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