You will be given a decimal number n in the form of a string. You must determine if that number, when stored in standard number type T in your language, is greater than, equal to, or less than the decimal representation. T can be anything appropriate for your language, such as a float, a double, or a generic "number" type etc, as long as it can represent the numbers to a reasonable accuracy and is not a decimal type.
For example, in python:
0.1
Is represented internally exactly by the value
0.1000000000000000055511151231257827021181583404541015625
The value 2 is represented internally by exactly the value 2.
You must determine, for a given decimal number, is the internal representation of that number greater than, equal to, or less than the decimal representation?
Input
- A string containing the decimal representation of the number
Output
- An indication of if the internal representation of that number is greater than, equal to, or less than to the input.
Rules
- Code golf scoring
- While
Tmust not be a decimal type, you can use decimal types in your code to facilitate your comparison.
-
\$\begingroup\$ Are always = decimal 0.1 is equal to 0.1000000000000000055511151231257827021181583404541015625 in binary xxx-float. The same all other \$\endgroup\$Rosario– Rosario2025年08月29日 11:54:11 +00:00Commented Aug 29 at 11:54
-
1\$\begingroup\$ @Rosario I'm not 100% sure what you mean but decimal 0.1 is equal to that number in python's default implementation. But it's up to you to choose what data type you use for your language of choice. \$\endgroup\$Ted– Ted2025年08月29日 12:12:42 +00:00Commented Aug 29 at 12:12
-
\$\begingroup\$ The title here presents a false dichotomy, since many computers have floating-point decimal types (for which systems this question reduces to a matter of whether the limits of range and precision are exceeded). \$\endgroup\$Toby Speight– Toby Speight2025年08月29日 15:21:29 +00:00Commented Aug 29 at 15:21
-
1\$\begingroup\$ Is it allowed to change the rounding behavior at runtime? C99 has fesetround that can affect the behavior of strtod, which is relevant to this challenge. \$\endgroup\$Explorer09– Explorer092025年08月29日 22:57:49 +00:00Commented Aug 29 at 22:57
-
1\$\begingroup\$ @Heinzi you can pick the format of your input within reason as long as it's a string \$\endgroup\$Ted– Ted2025年08月31日 02:53:20 +00:00Commented Aug 31 at 2:53
8 Answers 8
Java, (削除) 80 (削除ここまで) (削除) 79 (削除ここまで) (削除) 59 (削除ここまで) 57 bytes
s->s.compareTo(new java.math.BigDecimal(new Float(s))+"")
Outputs a negative integer if the internal floating point value is larger; 0 if they're the same; and a positive integer if the floating point is smaller.
Explanation:
s-> // Method with String parameter and integer return
s.compareTo( // Compare the input to (resulting in neg/0/pos):
new java.math.BigDecimal( // Create a BigDecimal, with value:
new Float(s)) // The (32-bit) floating point number of the input
+"") // Convert that BigDecimal to a String
Minor note: I've used Float (which is 32 bits) and therefore holds slightly different values than in the challenge description. If I would change it to Double (which is 64 bits) the values would be the same as the challenge description. This difference can for certain inputs also result in different outputs (e.g. the "0.09" is 0.0900000035762786865234375 as float, resulting in -23, but 0.0899999999999999966693309261245303787291049957275390625 as double, resulting in 1). The overall functionality would still be the same, though:
Try it online.
-
\$\begingroup\$ I don't quite understand why you can't use float? Since you can pick
T\$\endgroup\$Ted– Ted2025年08月29日 08:24:48 +00:00Commented Aug 29 at 8:24 -
1\$\begingroup\$ @Ted I guess either is fine indeed. I've just used
Floatnow, but still mentioned the difference withDoubleat the bottom of my answer. \$\endgroup\$Kevin Cruijssen– Kevin Cruijssen2025年08月29日 08:30:26 +00:00Commented Aug 29 at 8:30
Vyxal 3, 1 byte
1
Outputs 1 if equivalent, 0 if bigger, -1 if smaller. This probably polyglots a lot of languages lol. Leave a comment if you have a polyglot language where the answer is always 1.
Notably, this always outputs 1. That's because all numbers are stored exactly by default. That's an intentional language design decision we went out of our way to accommodate by using a third party library under the hood. Technically, the number type is called VNum which extends spire.Complex[Real], so not a "decimal" type but a type that happens to also be able to store decimals exactly by consequence of also storing things like surds exactly.
There's a slight chance this could be considered invalid by the "don't use decimal type" restriction, but that's up to the challenge asker as to whether the default (and only) generic number type being exact is allowed.
-
\$\begingroup\$ Polyglot equivalent with 05AB1E. \$\endgroup\$Kevin Cruijssen– Kevin Cruijssen2025年08月29日 07:53:07 +00:00Commented Aug 29 at 7:53
Python (v3.8+), 68 bytes
lambda d:(s>(t:=str(longdouble(float(d)))))-(s<t)
from numpy import*
Integers should be input with .0 (e.g. test case 2 is input as "2.0").
Outputs -1 if the internal floating point value is larger; 0 if they're the same; and 1 if the floating point is smaller.
Explanation:
lambda s: # Function with a string as argument
(s> # Check if the input-string is larger than:
(t:=str(longdouble(float(d)))))
# the internal floating point value of `s` as string
# (which is also stored in `t`)
-(s<t) # And subtract the s<t check from the s>t check to get -1/0/1
from numpy import* # Import for the `longdouble`
-
\$\begingroup\$ Don't I have to count the
import? \$\endgroup\$ojdo– ojdo2025年08月29日 08:04:32 +00:00Commented Aug 29 at 8:04 -
1\$\begingroup\$ I could indeed. Right now I have
Python + NumPyas language, so it's not competing with Python. But I'll change it to Python and include the import, so people see your Python answer is 1 byte shorter. :) \$\endgroup\$Kevin Cruijssen– Kevin Cruijssen2025年08月29日 08:18:31 +00:00Commented Aug 29 at 8:18 -
\$\begingroup\$ Ah I see, thanks for clarifying. \$\endgroup\$ojdo– ojdo2025年08月29日 08:20:24 +00:00Commented Aug 29 at 8:20
Python, (削除) 67 (削除ここまで) (削除) 65 (削除ここまで) 64 bytes
lambda n:D(n).compare(D(eval(n)))
from decimal import*;D=Decimal
"The obvious" as in using Decimal for the comparison. Only golfy idea is replacing float() by eval() to save 1 byte.
R, 50 bytes
f=\(x)(x>(y=sprintf("%.57g",as.numeric(x))))-(x<y)
Function f returns
0if the decimal representation is the same,1if larger,- and
-1if smaller.
Anything beyond 57th decimal place won't be stored. If you put 0 on 57th decimal, you'll get 1 from f(), since technically 0.123...789 is laregr than 0.123...7890.
-
1\$\begingroup\$ This can fail on inputs with more than 17 decimal places, such as
0.123456789123456781. If you bump up the format string to"%.99g", it still fails on inputs like0.12345678912345678379658409085095627233386039733886718750. \$\endgroup\$Dingus– Dingus2025年08月30日 00:20:27 +00:00Commented Aug 30 at 0:20 -
\$\begingroup\$ @Dingus that's not true though, is it? Try running
sprintf("%.999g",0.123456789123456789123456789123456789098765432109876543210123456789). I did pick 17 for a reason. R, by default, uses 64-bit double-precision floating-point numbers (IEEE 754 standard). \$\endgroup\$M--– M--2025年08月30日 04:05:13 +00:00Commented Aug 30 at 4:05 -
\$\begingroup\$ See for yourself. The expected output is
0. \$\endgroup\$Dingus– Dingus2025年08月30日 06:05:36 +00:00Commented Aug 30 at 6:05 -
\$\begingroup\$ @Dingus I dunno
0.123...750and0.123...75are not technically the same (different rounding errors). Putting a 0 on exactly 57th digit is the issue. Although anything beyond 17 decimal places is not exactly accurate, I concur, any number with 0 exactly at 57th place has the issue you are demonstrating; with the caveat I said above about rounding errors. Anyway, this is now beyond code golf and starting to get too too deep into language internals and design which I admittedly don't know much about both (CG or the other), but I am sure others might know more and would offer better solutions. \$\endgroup\$M--– M--2025年08月30日 14:01:09 +00:00Commented Aug 30 at 14:01
Maple, 44 bytes
s->sign(evalf[20]((r:=parse(s))-evalhf(r)));
Compares with hardware float type as internal representation. (Maple's default floats are decimal and so precluded by the rules.)
Inputs a string; output is -1 if the internal is greater, 0 if the same, and +1 if the internal is less.
The 20 here can be anything significantly more than 15, which is the approx. number of decimal digit accuracy for the hardware floats. Unfortunately the default software float accuracy is 10 digits and not some number higher than 15, otherwise we could get rid of evalf[20]() and save 11 bytes. evalhf converts to hardware float.
Charcoal, 25 bytes
≔∧Noθ.⌕⮌θ.η=∕NX·5η÷I−θ.X5η
Try it online! Link is to verbose version of code. Outputs a Charcoal boolean, i.e. - if the input can be represented in floating-point, nothing if not. Explanation:
≔∧Noθ.⌕⮌θ.η
Find the number of decimals (if any).
=∕NX·5η÷I−θ.X5η
Divide the input by .5 to that power, which converts it to a float if it isn't one already, without further loss of precision, then compare that to the result of integer dividing the input without a decimal point by 5 to that power.
-
\$\begingroup\$ I notice that the question has since been edited to ask for the sign of the difference. I can do this in 46 bytes:
≔∧Noθ.⌕⮌θ.η≔×∕NX·5ηX64χζ≔÷×I−θ.X64χX5ηεI−›ζε‹ζεLink is to verbose version of code. Works similarly to the equality check but adds in an extra scaling factor of260which makes the integer divide error negligible. \$\endgroup\$Neil– Neil2025年08月31日 17:10:39 +00:00Commented Aug 31 at 17:10
Explore related questions
See similar questions with these tags.