13
\$\begingroup\$

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 T must not be a decimal type, you can use decimal types in your code to facilitate your comparison.
asked Aug 29 at 6:44
\$\endgroup\$
13
  • \$\begingroup\$ Are always = decimal 0.1 is equal to 0.1000000000000000055511151231257827021181583404541015625 in binary xxx-float. The same all other \$\endgroup\$ Commented 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\$ Commented 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\$ Commented 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\$ Commented 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\$ Commented Aug 31 at 2:53

8 Answers 8

7
\$\begingroup\$

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.

Try it online.

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.

answered Aug 29 at 7:35
\$\endgroup\$
2
  • \$\begingroup\$ I don't quite understand why you can't use float? Since you can pick T \$\endgroup\$ Commented Aug 29 at 8:24
  • 1
    \$\begingroup\$ @Ted I guess either is fine indeed. I've just used Float now, but still mentioned the difference with Double at the bottom of my answer. \$\endgroup\$ Commented Aug 29 at 8:30
5
\$\begingroup\$

Vyxal 3, 1 byte

1

Vyxal It Online!

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.

answered Aug 29 at 7:24
\$\endgroup\$
1
  • \$\begingroup\$ Polyglot equivalent with 05AB1E. \$\endgroup\$ Commented Aug 29 at 7:53
5
\$\begingroup\$

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.

Try it online.

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`
answered Aug 29 at 7:16
\$\endgroup\$
3
  • \$\begingroup\$ Don't I have to count the import? \$\endgroup\$ Commented Aug 29 at 8:04
  • 1
    \$\begingroup\$ I could indeed. Right now I have Python + NumPy as 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\$ Commented Aug 29 at 8:18
  • \$\begingroup\$ Ah I see, thanks for clarifying. \$\endgroup\$ Commented Aug 29 at 8:20
5
\$\begingroup\$

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.

Attempt This Online!

answered Aug 29 at 8:02
\$\endgroup\$
5
\$\begingroup\$

Haskell, 33 bytes

compare=<<realToFrac.fromRational

Try it online!

answered Aug 30 at 9:32
\$\endgroup\$
3
\$\begingroup\$

R, 50 bytes

f=\(x)(x>(y=sprintf("%.57g",as.numeric(x))))-(x<y)

Attempt This Online!

Function f returns

  • 0 if the decimal representation is the same,
  • 1 if larger,
  • and -1 if 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.

See the point about 57th decimal online.

answered Aug 29 at 16:52
\$\endgroup\$
4
  • 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 like 0.12345678912345678379658409085095627233386039733886718750. \$\endgroup\$ Commented 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\$ Commented Aug 30 at 4:05
  • \$\begingroup\$ See for yourself. The expected output is 0. \$\endgroup\$ Commented Aug 30 at 6:05
  • \$\begingroup\$ @Dingus I dunno 0.123...750 and 0.123...75 are 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\$ Commented Aug 30 at 14:01
2
\$\begingroup\$

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.

answered Aug 29 at 22:31
\$\endgroup\$
2
\$\begingroup\$

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.

answered Aug 30 at 9:22
\$\endgroup\$
1
  • \$\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 of 260 which makes the integer divide error negligible. \$\endgroup\$ Commented Aug 31 at 17:10

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.