views:

389

answers:

9

Given any number of the random real numbers from the interval [0,1] is there exist any method to construct a floating point number with zero fractional part?

Your algorithm can use only random() function calls and no variables or constants. No constants and variables are allowed, no type casting is allowed. You can use for/while, if/else or any other programming language operands.

A: 
float random_float() {
     return random(); // POSIX random returns a long.
} //  I assume that's what OP means, no indication otherwise.

Considering that you didn't even specify that the returned floats are supposed to be random, much less what distribution they should have, I think this is the best we can do.

The above does contain a typecast, but there is no way to construct a floating-point number without either using a floating-point constant 0. or 1. or a value from a FP-valued function, which random is not.

To cheat a bit (this produces a different distribution and is rather unstable):

float random_float() {
     if ( random() < random() ) {
         return expf( float() ) + random_float();
     } else return expf( float() ); // expf(float()) just a fancy name for 1
}

By the way, actual real numbers are beyond the grasp of computers. Inputting one would take infinite time.

Potatoswatter
but there is a specification that they should be integers
jk
That does not generate a number with 0 as decimal part, does it?
nico
@nico: the specification is a 0 in the fractional part. @jk: yes, `random` produces an integer. See `man random`.
Potatoswatter
if the random refered to in the question is posix random you are casting, if its the real[sic] number in the range [0,1] then you dont produce integers
jk
@jk: read the post.
Potatoswatter
+4  A: 

Best I've come up with so far: generate a list of N random numbers, multiply them all together, this will go to 0 (which has a 0 fractional part) when N is large enough.

OK, I used a variable (N), but I'm not sure how to use for loops or if statements without a variable or constant.

If I had more time and the inclination I expect that I could prove that the product of N floats (or doubles) will go to 0 under IEEE arithmetic. As it is I played around with Matlab, and N == 800 seems sufficient.

EDIT: OP's insistence on avoiding all constants and variables leads me next to this solution:

random() * random() * random() * ...

I'll spare you all the other 797 calls to random. To all of you whose skulls split asunder at this mind-bogglingly ridiculous solution, may I point you to the question.

Lest you wonder or worry, I haven't a clue what random() returns in your language, here in my pseudocode it returns a floating-point number with as many bits as I wish (32, 64, 157 if I want) in the range [0,1] as required.

High Performance Mark
You cannot use any constants in your algorithm.
psihodelia
To avoid N, how about `x = rand(); while (x) x *= rand();` ?
mtrw
@mtrw: your x looks like a variable to me and @psihodelia is very strict
High Performance Mark
you cannot use rand() because it returns integer numbers
psihodelia
This doesn't work since in theory the first 799 calls to `random()` could return 1 and the last on 0.5
Andreas Brinck
@High - my mistake. Unfortunately I was taught "Data Structures + Algorithms = Programs". Without a data structure I confess I'm a little lost.
mtrw
@Andreas Brinck: Well, I guess we can call that a negligible bug, since it will happen in 0.00000000000000000000000000..............1% of cases
nico
@nico This kind of negates the point of the whole question.
Andreas Brinck
@Andreas Brinck: Well, it works in the vast majority of cases. I would still call this an exact algorithm, considering the (pointless) strictness of the "game rules".
nico
@nico I disagree, a program is either correct or incorrect, it can't be nearly correct.
Andreas Brinck
@Andreas Brinck: no software is without bugs. This program has a bug: once every 10000000000 years it doesn't give the correct results. I would say that is a very good piece of software.
nico
@High Performance Mark LOL
Shravan
@Andreas: I have never found a pseudo-random number generator which could, in theory or practice, return a stream of 799 1s and one 0.5 (say). All the PRNGs I have ever come across will not produce two consecutive identical numbers. That's one of the reasons they are called pseudo.
High Performance Mark
A: 
TheMachineCharmer
You're using a constant: `ZERO`
Andreas Brinck
Also in the problem statment it says the number are in the `[0, 1]` range and not the `(0, 1)` range.
Andreas Brinck
And you're using VARIABLES!
mtrw
No variables are allowed.
psihodelia
+4  A: 

Here's a solution in Python:

from random import random

def positiverandom():
    return random() or positiverandom()

def zerofraction():
    return (positiverandom() == -positiverandom()) * random()

Usage example:

>>> zerofraction()
0.0
Pär Wieslander
What if the two first `random()` returns 0 and the last 0.5
Andreas Brinck
What's the point of that? It has a small but finite chance of returning the value of `random()`, otherwise it returns 0.
Potatoswatter
Good point, didn't take the case where the first two `random()` calls both return zero into account.
Pär Wieslander
Updated the solution. This one should be bullet-proof.
Pär Wieslander
It looks like `positiverandom` could lead to infinite recursion.
Andreas Brinck
@Andreas Brinck: No, `positiverandom()` can't lead to infinite recursion. If `random()` keeps returning 0.0 the sequence of random numbers is not, by definition, random.
Pär Wieslander
@Pär You're incorrect, `positiverandom` will *eventually* return a `value != 0` but you could theoretically have infinitely many 0 before.
Andreas Brinck
You can't have infinitely many 0 before something happens!Anyway, the probability of a number in [0, 1] being 0 is zero.
Rawling
Yes you can, because `infinity + 1 == infinity`. As for the other point that's faulty logic, you could as well say that the probability of a number in [0, 1] begin 0.5 is zero...
Andreas Brinck
Yup! The probability of a number in [0, 1] being 0.5 is zero! (Edit: random unidormly distributed number, that is.)
Rawling
@Rawling This would mean that any result of `random()` would have an a priori probability of zero. I think the flaw here is the assumption that you can construct a `random()` that returns a true random number, if you look at `http://en.wikipedia.org/wiki/Real_numbers` you'll see that most real numbers are not computable because the real numbers are not countable.
Andreas Brinck
Sorry :) I was a maths student, I (probably being deliberately obtuse) took the question's reference to "real numbers from [0,1]" to mean that, rather than "real numbers representable in a data type I'm not specifying".
Rawling
+4  A: 
return ceil(random())

works.

If you allow only operators like +, -, *, sin you can prove that:

Every expression built using random variables from U[0,1] and arithmetic operations, using each random variable exactly once will represent an irrational number with probability 1.

Since your program must end with return expression it will be wrong (or won't halt) with probability 1.

sdcvvc
You are not allowed to use any functions but random().
psihodelia
Aww... I was so excited for you sdcvvc. Now I had to retract everything and begin to despair again. I still think it was clever enough.
erisco
psihodelia, please list all allowed "other programming language operands" and arithmetic operations. Are real numbers represented exactly and is random() a true RNG? Otherwise, it's a guessing game like http://xkcd.com/169/
sdcvvc
I think we're just being strung along, I have a feeling that when psihodelia eventually presents his answer, I will be really, really disappointed...
Andreas Brinck
random() is usual C function, which returns a floating point number from [0,1]. You can use any programming construction you like, but you cannot use any library function but random().
psihodelia
+2  A: 
 float random_float() {
     return 1.0;   /* chosen by random sphere roll, guaranteed to be random */
 }
Alnitak
+1 for the reference :-)
Vicky
+1  A: 

Here we go!

<?php

random();

function random() {
    return 1.0;
}

As long as I can tell the story that 1.0 is quite correctly one of the random numbers in the interval [0, 1].

I did not use constants! My algorithm is the call to random(), not the implementation of random(). PHP just doesn't happen to have such a function so I had to make it myself, conveniently.

erisco
PHP does have `rand()` though.And 1.0 IS a constant!
nico
`rand()` does not return a float, and I explained the constant in my answer.
erisco
@erisco: Don't cheat! ;) You `return 1.0` so you use a constant!!! :)
nico
A: 

Bitwise AND the FP representations of all your real numbers together.

Vicky
+3  A: 

In Python:

>>> (-random() > random())*random()
0.0

But no doubt I'm going to be told that this violates some unwritten, yet-to-be-revealed condition of this bizarre problem.

Mark Dickinson
Congratulations, this is right solution.
psihodelia
I thought you said no type casting, doesn't this cast a a boolean expression `(-random() > random())` to a float?
Andreas Brinck
There's certainly an implicit conversion in there (which technically may or may not be the same thing as a cast, depending on exactly which language we're supposed to be talking about).
Mark Dickinson
Sigh, so this whole question was about whether you recognized that casting is an explicit type conversion, leaving implicit conversions - coercion - free for use. I call complete bogus on this question as this solution is only possible with languages that support coercion, including the coercion from boolean false to real zero!
erisco
-1 I downvoted this for breaching the clearly established requirements of the question.
High Performance Mark
@High Performance Mark: which requirement was breached? There are no casts here: an implicit conversion is not a cast, either in C or in Python.
Mark Dickinson