4
\$\begingroup\$

As you may know, the typical binary floating point numbers in a computer language are quite different than the typical integer numbers in a computer language. Floating point numbers can represent a much larger range, and can represent fractional amounts, however there is a trade-off that is frequently elided.

The distance between integers is constant, and in fact the value of that constant is one. The distance between floating point numbers, however, is variable, and increases the further one travels down the number line, away from the origin at 0. At some point, that distance is so large that the floating point numbers start skipping over integers, and many integers that are technically less than the maximum value of the floating point numbers, cannot actually be represented by floating point numbers.

The challenge:

Write a program that when given the number n, will print out the first n positive integers that cannot be represented by a floating point number in your language of choice.

  • "First n positive integers" means, lowest in value, closest to the origin, and distinct from each other.

  • Infinite precision floating point numbers are not allowed.

  • It doesn't matter whether you choose 32 bit floats, 64 bits floats, or some other type of float, as long as it is a non-infinite precision floating point number in your language of choice, on your machine of choice.

  • Order of numbers does not matter

  • This is Code Gofl. Smallest number of characters wins.

  • Good luck and have fun

Example:

In Rust, using 32 bit floating point builtin type 'f32':

n=4, result = [16777217,16777219,16777221,16777223]

(updated - 1 order doesnt matter - 2 Golf->Gofl)

\$\endgroup\$
12
  • \$\begingroup\$ Smallest number of characters wins I think you mean bytes. If not, is there a reason you're using characters? \$\endgroup\$
    – Jo King
    Feb 26, 2019 at 5:26
  • \$\begingroup\$ i just love unicode? \$\endgroup\$
    – don bright
    Feb 26, 2019 at 5:28
  • 1
    \$\begingroup\$ @xnor I don't think it should include this just because most language use IEEE754 floating point numbers. Other form of floating point numbers should be allowed although I don't know one. \$\endgroup\$
    – tsh
    Feb 26, 2019 at 9:03
  • 2
    \$\begingroup\$ @donbright I recommend scoring in bytes. The reason is that, otherwise, the full code in ASCII-only golfing languages (such as CJam or Pyth) can be compressed in a unicode string that will unpack to the ASCII-only code, therefore saving characters, but not bytes. Furthermore, the byte is the actual unit of digital data storage, while "character" is a term that depends on the encoding the solution uses, and one character can even take up 6 bytes, for example. This is how the "packing" mentioned before worked before we changed the default scoring method for code-golf to the byte count. \$\endgroup\$ Feb 26, 2019 at 20:45
  • 1
    \$\begingroup\$ @Sara-J order does not matter. Updated, thanks. \$\endgroup\$
    – don bright
    Feb 26, 2019 at 23:43

9 Answers 9

3
\$\begingroup\$

C (gcc), 58 bytes

f(n,i){for(i=9;n;i++)i-(int)(i+.0f)&&printf("%d ",i,n--);}

Try it online!

Works with 32-bit float.

\$\endgroup\$
3
\$\begingroup\$

Perl 6, 28 characters

{grep({.Num+|0-$_},^∞)[^$_]}

Try it online!

This is actually 30 bytes, but the challenge is scored in characters.

This should work theoretically. This creates a lazy list of numbers that compares the default number type (with arbitrary precision) against the same number converted to a Num datatype, which is a 64-bit floating point number, and returns the first \$n\$ elements of the list

Here's a version starting at \$2^{53}-5\$

\$\endgroup\$
1
  • 1
    \$\begingroup\$ i like the infinity literal. \$\endgroup\$
    – don bright
    Mar 4, 2019 at 1:50
2
\$\begingroup\$

Ruby 2.6, 42 bytes

->n{(1..).lazy.select{|i|i!=i*1.0}.take n}

Works with 64-bit floats, returns an enumerator.

Ruby 2.5 and below, 43 bytes

->n{1.step.lazy.select{|i|i!=i*1.0}.take n}

And finally, the one that actually finishes in reasonable time:

->n{(2**53).step.lazy.select{|i|i!=i*1.0}.take n}

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ cool, i didnt realize ruby could do that \$\endgroup\$
    – don bright
    Mar 4, 2019 at 1:49
2
\$\begingroup\$

Java 8, 68 67 bytes

n->{for(int i=9;;)if(++i!=(int)(i+0f))System.out.println(i*n/n--);}

Uses the 32-bit float, but by changing 0f to 0d and int to long it can also be tested with the 64-bit double.

Try it online with int and 0f.
Try it online with long and 0d.

Explanation:

n->{                       // Method with integer parameter and no return-type
  for(int i=9;;)           //  Loop `i` from 9 upwards indefinitely:
    if(++i                 //   Increase `i` by 1 first
          !=               //   And if it does not equal:
            (int)(i+0f))   //   Itself as float, and casted back to integer:
      System.out.println(i //    Print the current `i`
        *n/n--);}          //    And decrease `n` by 1
                           //    (and due to the `n/n`, the infinite loop will stop as soon
                           //     as `n` becomes 0, with a division by zero error)
\$\endgroup\$
2
\$\begingroup\$

JavaScript, 46 bytes

n=>{for(x=1n;n;)+[++x]!=x&&console.log(x)&n--}

This will certainly timeout on TIO. So, here is a TIO link which initialize x with 253.


  • Save 7 10 bytes, thanks to Neil.
  • Save 2 bytes, thanks to Arnauld
\$\endgroup\$
6
  • \$\begingroup\$ So sad SpiderMonkey do not support bigint yet. Otherwise we can save many bytes by switching to SpiderMonkey and use print. \$\endgroup\$
    – tsh
    Feb 26, 2019 at 9:06
  • \$\begingroup\$ Number(++x)!=x saves 5 bytes. \$\endgroup\$
    – Neil
    Feb 26, 2019 at 9:30
  • \$\begingroup\$ @Neil I remembered that one cannot mix number with bigint. But I didn't know they can check equality without explicit type convertion.+(++x+'') would be shorter than Number(++x). \$\endgroup\$
    – tsh
    Feb 26, 2019 at 9:42
  • \$\begingroup\$ Would something like this work? \$\endgroup\$
    – Oliver
    Feb 26, 2019 at 16:31
  • \$\begingroup\$ @Oliver It should work for small n. Try to pass n = 1000 and initial x as 2**54, you will find out the difference. \$\endgroup\$
    – tsh
    Feb 27, 2019 at 2:31
1
\$\begingroup\$

cQuents, 9 bytes

&#N_=N+.0

Try it online!

& is broken on TIO right now, so TIO link will not work, but it would time out anyway, as the only way to start at 2^53 is modifing the interpreter.

Explanation

           Implicit input n
&          Output first n terms of the sequence
 #         Only include an integer N in the sequence if:
  N        N
   _=        is not equal to 
     N+.0                    N converted to float
\$\endgroup\$
5
  • \$\begingroup\$ how can i run this on my machine? i cloned github and typed python cquents.py , pasted the program and got an error \$\endgroup\$
    – don bright
    Feb 27, 2019 at 0:09
  • \$\begingroup\$ @donbright put the code in the source.cq file \$\endgroup\$
    – Stephen
    Feb 27, 2019 at 1:49
  • \$\begingroup\$ python cquents.py \n 5 \n cquents_core.CQSyntaxError: Unknown factor : EOF .... cquents_core.CQSyntaxError: Unknown factor : & \$\endgroup\$
    – don bright
    Feb 28, 2019 at 1:39
  • \$\begingroup\$ @donbright uh you might have a trailing newline in your source.cq file? That would cause that error. If you want to test it without waiting change line 169 in cquents_core.py to self.n = 2 ** 53. \$\endgroup\$
    – Stephen
    Feb 28, 2019 at 2:11
  • 1
    \$\begingroup\$ congratulations, fascinating language \$\endgroup\$
    – don bright
    Mar 4, 2019 at 1:46
1
\$\begingroup\$

Python 2, 57 bytes

n=1
exec"while n==int(.0+n):n+=1\nprint n;n+=1\n"*input()

Starting from 1 takes a very long time. For testing purposes, starting at \$2^{53}\$ gives the same results but much quicker: Try it online!

We count up values of n (an integer) until we find one for which converting to a float (by adding .0) and back to an int doesn't result in the same number. We then print that value and go to the next n. An exec loop lets us do this a fixed number of times according to the input.

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

C# (Visual C# Interactive Compiler), 54 bytes

n=>{for(int i=1;;)if(++i!=(int)(i+0f))Print(i*n/n--);}

Port of Kevin Cruijssen's Java answer

Try it online!

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

05AB1E (legacy), 10 bytes

µ¾ÐtnïÊi,¼

No TIO, because it will time out way before it reaches the first number 9007199254740993.. I'm using the legacy, since it is run in Python, so will output the same numbers as the Python answer. I'll see if I can determine the first few numbers for the new version of 05AB1E as well, which is run in Elixir (but that will be a separated answer in that case).

As alternative for the TIO, here a prove that tnï for input 9007199254740993 does not result in 9007199254740993, but in 9007199254740994 instead: Try it online.

Explanation:

µ           # Loop until the counter_variable is equal to the (implicit) input
            # (the counter_variable is 0 by default)
 ¾Ð         #  Push the counter_variable three times
   t        #  Take its square-root
    n       #  And then the square of that
     ï      #  And cast it back from a decimal to an integer
      Êi    #  If they are NOT equal:
        ,   #   Print the counter_variable
         ¼  #   And increase the counter_variable by 1

05AB1E has no builtin to set the counter_variable manually unfortunately, otherwise I would have set it to about 9007199254740000 at the start.

\$\endgroup\$
4
  • \$\begingroup\$ how can i run o5ab1e legacy version on my own machine? \$\endgroup\$
    – don bright
    Feb 28, 2019 at 1:42
  • \$\begingroup\$ @donbright I'm not entirely sure, but if I look back at the commit history, this commit from July 9th, 2018 was the last commit made in the Python legacy 05AB1E. The commit after that was the start of the Elixir rewrite. So I think you can check out the code from that commit, and then run it with Python with the instructions given in the README of that version. \$\endgroup\$ Feb 28, 2019 at 7:23
  • \$\begingroup\$ @donbright If you need any help, I suggest pinging @Adnan on the 05AB1E chat, since he's the one who made and manages the 05AB1E code (PS: If he doesn't respond, Emigna or Don't be a x-triple dot would probably know as well. I personally primarily use 05AB1E on TIO tbh.) \$\endgroup\$ Feb 28, 2019 at 7:24
  • \$\begingroup\$ thanks. however cquents was one byte shorter. \$\endgroup\$
    – don bright
    Mar 4, 2019 at 1:48

Your Answer

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

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