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)
9 Answers 9
Perl 6, 28 characters
{grep({.Num+|0-$_},^∞)[^$_]}
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
-
1\$\begingroup\$ i like the infinity literal. \$\endgroup\$don bright– don bright2019年03月04日 01:50:00 +00:00Commented Mar 4, 2019 at 1:50
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}
-
\$\begingroup\$ cool, i didnt realize ruby could do that \$\endgroup\$don bright– don bright2019年03月04日 01:49:17 +00:00Commented Mar 4, 2019 at 1:49
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)
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
-
\$\begingroup\$ So sad SpiderMonkey do not support bigint yet. Otherwise we can save many bytes by switching to SpiderMonkey and use
print. \$\endgroup\$tsh– tsh2019年02月26日 09:06:13 +00:00Commented Feb 26, 2019 at 9:06 -
\$\begingroup\$ Number(++x)!=x saves 5 bytes. \$\endgroup\$Neil– Neil2019年02月26日 09:30:34 +00:00Commented 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 thanNumber(++x). \$\endgroup\$tsh– tsh2019年02月26日 09:42:06 +00:00Commented Feb 26, 2019 at 9:42 -
-
\$\begingroup\$ @Oliver It should work for small
n. Try to passn = 1000and initial x as 2**54, you will find out the difference. \$\endgroup\$tsh– tsh2019年02月27日 02:31:56 +00:00Commented Feb 27, 2019 at 2:31
cQuents, 9 bytes
&#N_=N+.0
& 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
-
\$\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– don bright2019年02月27日 00:09:31 +00:00Commented Feb 27, 2019 at 0:09
-
\$\begingroup\$ @donbright put the code in the source.cq file \$\endgroup\$Stephen– Stephen2019年02月27日 01:49:04 +00:00Commented 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– don bright2019年02月28日 01:39:04 +00:00Commented 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– Stephen2019年02月28日 02:11:12 +00:00Commented Feb 28, 2019 at 2:11 -
1\$\begingroup\$ congratulations, fascinating language \$\endgroup\$don bright– don bright2019年03月04日 01:46:41 +00:00Commented Mar 4, 2019 at 1:46
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.
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
05AB1E (legacy), 10 bytes
μ3⁄4ÐtnïÊi,1⁄4
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)
3⁄4Ð # 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
1⁄4 # 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.
-
\$\begingroup\$ how can i run o5ab1e legacy version on my own machine? \$\endgroup\$don bright– don bright2019年02月28日 01:42:03 +00:00Commented 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\$Kevin Cruijssen– Kevin Cruijssen2019年02月28日 07:23:48 +00:00Commented 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\$Kevin Cruijssen– Kevin Cruijssen2019年02月28日 07:24:09 +00:00Commented Feb 28, 2019 at 7:24
-
\$\begingroup\$ thanks. however cquents was one byte shorter. \$\endgroup\$don bright– don bright2019年03月04日 01:48:21 +00:00Commented Mar 4, 2019 at 1:48
Smallest number of characters winsI think you meanbytes. If not, is there a reason you're using characters? \$\endgroup\$