What does c = t < 0 in C mean?

  • Java
  • Thread starter Paul Uszak
  • Start date
  • Tags
    Mean
In summary: In C, with c and t as integersc = t > 0This is the entire code (sic). Should have posted it earlier. Now I'm starting to doubt that it's C at all. I assumed that it was C.It's from:-Good Practice in (Pseudo) Random Number Generation for Bioinformatics ApplicationsDavid Jones, UCL Bioinformatics Group(Last revised May 7th 2010)In C, with c and t as integers, c = t > 0.
  • #1
Paul Uszak
84
7
This is a very basic question, but one that's vexed me for a while. Are these two fragments equal:-In C, with c and t as integers
c = t < 0

and in Java, also with integers
if (t < 0) {
c = -1;
} else {
c = 0;
}


Reason I ask is that my Java interpretation works with any combination of t & c, and I can't tell which is the correct translation...
 
Technology news on Phys.org
  • #2
Paul Uszak said:
This is a very basic question, but one that's vexed me for a while. Are these two fragments equal:-In C, with c and t as integers
c = t < 0

and in Java, also with integers
if (t < 0) {
c = -1;
} else {
c = 0;
}


Reason I ask is that my Java interpretation works with any combination of t & c, and I can't tell which is the correct translation...
I don't do JAVA but my understanding is that it is a strongly typed language and as such it should have inherent "true" and "false" variables and your c variable in JAVA should be typed as boolean, so I'd say your JAVA statements should use true and false, not -1 and 0. Does JAVA do auto-conversion from integer to Boolean?
 
  • #3
Paul Uszak said:
Are these two fragments equal:-In C, with c and t as integers
c = t < 0

and in Java, also with integers
if (t < 0) {
c = -1;
} else {
c = 0;
}
No. Fortran has this right. C/C++, and languages based on it such as Java, have it wrong (in my opinion).

In C, c = t < 0 sets c to zero or one. The problem with that is that zero and one differ by one bit. This is not a good idea in an environment that is prone to random bit flips.

OTOH, Fortran seeks to make boolean expressions such as t < 0 evaluate to two values that are diametrically opposed, bitwise. Your Java code emulates how Fortran works. It uses -1(all bits set on a two's complement machine) rather than 1 (only the least significant bit set).
 
  • #4
Paul Uszak said:
In C, with c and t as integers
c = t < 0

In C, this is read as c = (t < 0) and does the same thing as
C:
if (t < 0) {
    c = 1;
} else {
    c = 0;
}

Java has a separate boolean type and doesn't support casting booleans to integers or vice versa, so in Java c = t < 0 is equivalent to
Java:
if (t < 0) {
    c = true;
} else {
    c = false;
}
which the compiler will choke on if c is of type int.

How to "translate" the C code into Java depends on why you're doing this and what you want to accomplish. If there's a specific reason you want to assign integers like 1 or 0 to c, then assign those integers. If you just want to save the result of a test, then make c a boolean:
Java:
boolean c;

c = t < 0;
[Edit: Since C99, C also defines a boolean type (_Bool), but it's effectively an integer that can only be assigned values 0 and 1 and isn't integrated into the language the way boolean is in Java (e.g. the C language standard says that the value of the expression t < 0 is of type int rather than _Bool).]
 
Last edited:
  • #5
This is the entire code (sic). Should have posted it earlier. Now I'm starting to doubt that it's C at all. I assumed that it was C. It's from:-

Good Practice in (Pseudo) Random Number Generation for Bioinformatics Applications
David Jones, UCL Bioinformatics Group
(Last revised May 7th 2010)
Code:
/* Implementation of a 32-bit KISS generator which uses no multiply instructions */
static unsigned int x=123456789,y=234567891,z=345678912,w=456789123,c=0;
unsigned int JKISS32()
{
int t;
y ^= (y<<5); y ^= (y>>7); y ^= (y<<22);
t = z+w+c; z = w; c = t < 0; w = t&2147483647;
x += 1411392427;
return x + y + w;
}

My problem lurks within the line beginning t = z... I think that c must be a number and not a boolean as it's used in an addition in this line. The code runs with my interpretation, but also with others and all produce reasonable output. This means I can't fix it. So help please!
 
  • #6
By precedence, one can rewrite it as c = (t > 0), and the equals sign expresses assignment. So that means c is?

Also, in C, what is 1 + false?
 
  • #7
Paul Uszak said:
This is the entire code (sic). Should have posted it earlier. Now I'm starting to doubt that it's C at all. I assumed that it was C. It's from:-

Good Practice in (Pseudo) Random Number Generation for Bioinformatics Applications
David Jones, UCL Bioinformatics Group
(Last revised May 7th 2010)
Code:
/* Implementation of a 32-bit KISS generator which uses no multiply instructions */
static unsigned int x=123456789,y=234567891,z=345678912,w=456789123,c=0;
unsigned int JKISS32()
{
int t;
y ^= (y<<5); y ^= (y>>7); y ^= (y<<22);
t = z+w+c; z = w; c = t < 0; w = t&2147483647;
x += 1411392427;
return x + y + w;
}

My problem lurks within the line beginning t = z... I think that c must be a number and not a boolean as it's used in an addition in this line. The code runs with my interpretation, but also with others and all produce reasonable output. This means I can't fix it. So help please!

That's C code, but (among other things) it's meant to be easy to translate to languages that don't have an unsigned integer type (like Java). It's written not to use multiplication because multiplication works differently for signed and unsigned integers.

To get the equivalent result in Java:
  • Change y ^= (y>>7); to y ^= (y>>>7); (i.e., use Java's "unsigned right shift" operator).
  • Change c = t < 0; to c = (t < 0) ? 1 : 0;.

It's probably a good idea to try out both the C and Java versions and check that they produce the same sequence.
 
Last edited:
  • #8
wle said:
  • Change y ^= (y>>7); to y ^= (y>>>7); (i.e., use Java's "unsigned right shift" operator).
  • Change c = t < 0; to c = (t < 0) ? 1 : 0;.
Thanks. And should all the variables be longs or shorts, because again it works well with both..? I suspect longs if they're to operate unsigned. But then it's meant to be 32 bit and not 64 bit. (I HATE SIGNED JAVA :mad: ESPECIALLY BYTES)
 
  • #9
int, since the algorithm is meant for 32 bit integers. Some of the numbers will be interpreted as negative in Java, e.g. if you print them to the console or multiply them by other numbers, but the bit sequences in memory should be the same.

If you really need the result to be a positive integer, you can always add 2L << 31 (i.e., ##2^{32}##) if the result is negative and save the result as a long at the end.
 
  • #10
Okay, I see some dangerous talk about types here.

Remember
char <= short <= int <= long <= long long

You have absolutely no guarantee that an int is 32 bits, you don't even have a guarantee that these are different. If you want to assure yourself certain sizes:

Code:
#include <cstdint>

int8_t my8bit = 111;  //Always 8 bit
int16_t my16bit = 1111; //Always 16 bit
int32_t my32bit = 11111;  //Always 32 bit
 
  • #11
Paul Uszak said:
This is the entire code (sic). Should have posted it earlier. Now I'm starting to doubt that it's C at all. I assumed that it was C.
It's definitely C code. In C, the comparison operators (<, >=, >, <=, ==, !=) evaluate to zero or one, not false or true.

Why are you using this? In one thread, you want bits from pi as a source of pseudo random numbers. Now you are trying to use some variant of KISS. Why? I've asked you before, you haven't answered.The answer to "Is X a good source of pseudo random numbers" depends very much on the application. If your goal is to add a bit of apparent randomness to a video game, even rand() is probably OK. You need to toss rand() if your goal is to perform some Monte Carlo analyses that depend on a PRNG with good frequency behaviors. Mersenne Twister works great (and is very fast) for this kind of application. You need to toss Mersenne Twister if your goal is cryptographically secure encryption. You also need to toss bits from pi, KISS, and a boatload of other pseudo random generators. Generating a sequence of cryptographically secure random numbers is a hard problem. There are cryptographically secure PRNGs, but in general they aren't very good for video games or Monte Carlo (too slow).

So what is your application?
 
  • #12
newjerseyrunner said:
Okay, I see some dangerous talk about types here.

Remember
char <= short <= int <= long <= long long

You have absolutely no guarantee that an int is 32 bits, you don't even have a guarantee that these are different.

This is all fixed in Java: ints are 32 bit signed two's complement integers that wrap around on overflow. It's not platform-dependent like in C.
 
  • #13
wle said:
This is all fixed in Java: ints are 32 bit signed two's complement integers that wrap around on overflow. It's not platform-dependent like in C.
Endianness is consistent too, where in lower level languages, you have no guarentee
 
  • #14
this compiles as C code(gcc 3.4.2) : gcc -C -Wall kiss.c
Code:
// unrolling this code so you can see it better.
// file:kiss.c
/* Implementation of a 32-bit KISS generator which uses no multiply instructions */
static unsigned int x=123456789,
                    y=234567891,
                    z=345678912,
                    w=456789123,
                    c=0;  // c is zero here
unsigned int JKISS32()
{
  int t;
  y ^= (y<<5);
  y ^= (y>>7);
  y ^= (y<<22);
  t = z+w+c;    // c is still zero here
  z = w;
  c = t < 0;    // c becomes 0 or 1 here
  w = t&2147483647; // no c here
  x += 1411392427;  // no c here
  return x + y + w;
}
MY question is:
Where does c have ANY effect on ANY calculation above as presented?
Code:
c = t < 0;
is dead code unless the c variable is used somewhere else.
For example JKISS32() is called from a loop somewhere else we cannot see -- which is my guess.
c varies from 0 to 1 depending on whether the t variable is negative or not negative assuming this code is called iteratively.
 
Last edited:
  • #15
jim mcnamara said:
For example JKISS32() is called from a loop somewhere else we cannot see -- which is my guess.
c varies from 0 to 1 depending on whether the t variable is negative or not negative assuming this code is called iteratively.

Well that's the point. c can be set to 1, which can affect subsequent calls of JKISS32().

(In case you haven't read the whole thread, JKISS32() is meant to generate a pseudo-random sequence of numbers, so presumably it's going to be called more than once. Otherwise you may as well just do this.)
 
  • #16
jim mcnamara said:
MY question is:
Where does c have ANY effect on ANY calculation above as presented?
The current value of c impacts the output from JKISS32 via the calculation t = z+w+c. The updated value of c will affect the output from the next call to JKISS32(). This is a "Keep It Simple and Stupid" (hence the name) pseudo random number generator. Presumably it will be called many, many times during the course of an application's execution.
 
  • #17
Thanks all so far for your patiences.

I've run the following with amendments suggested in this thread...

Code:
public static void main(String[] args) {
        int x = 123456789, y = 234567891, z = 345678912, w = 456789123, c = 0, t;        for (int i = 0; i < 10; i++) {
            y ^= (y << 5);
            y ^= (y >>> 7);                    // One > added from PF
            y ^= (y << 22);
            t = z + w + c;
            z = w;
            c = (t < 0) ? 1 : 0;               // 1 or 0 amendment from PF
            w = t & 2147483647;
            x += 1411392427;
            int next = x + y + w;
            System.out.println(next);
        }
    }

which produces this output...

-1714832263
-368852369
653136079
-1337015847
-162232845
-312426689
-302024013
-538639081
-639205643
-541828828
-204917723
1413940082
850185154
-87394344
-1847399219
-563371111
1218772128
-1940900712
-1922709363
-1395979365

This looks reasonable, if a little negative. Is there are chivalrous knight out there that might compile and execute the original C code for comparison? I don't have the resources to do so myself and I get a D in C.
 
  • #18
With regard to c - please note what I said later on. If the function were iterated it would have an effect, but did nothing to change the return value as presented.
The question seemed to be posed from the point of view of: ignoring iteration for the benefit of learning.
 
  • #19
Sure:
Code:
$ clang jkiss.c
$ ./a.out
-1714832263
 -368852369
  653136079
-1337015847
 -162232845
 -312426689
 -302024013
 -538639081
 -639205643
 -541828828
 -204917723
 1413940082
  850185154
  -87394344
-1847399219
 -563371111
 1218772128
-1940900712
-1922709363
-1395979365

Exact code run:
C:
#include <stdio.h>

static unsigned int x = 123456789, y = 234567891,
                    z = 345678912, w = 456789123, c = 0;

unsigned int jkiss32(void)
{
    int t;
    y ^= y << 5;
    y ^= y >> 7;
    y ^= y << 22;
    t = z + w + c;
    z = w;
    c = t < 0;
    w = t & 2147483647;
    x += 1411392427;
    return x + y + w;
}

int main(void)
{
    for (int i = 0; i < 20; ++i)
        printf("%11d\n", (int)jkiss32());
    return 0;
}

I printed the result as an int to compare the negative values.
 
Last edited:
  • #20
You should also really consider structuring the Java code instead of dumping the JKISS algorithm in main(). Java annoyingly insists that you pretend your entire program is object-oriented even when it's not, and I haven't used it in about ten years, so I'm not sure what the best way to handle this is. One approach might be to make the random number generator a static function in its own class (my recollection is that the math library is or was implemented this way), pretending it's a namespace:
Java:
import java.io.*;

class JKISS {
    static int x = 123456789, y = 234567891,
               z = 345678912, w = 456789123, c = 0;

    static int jkiss32() {
        int t;
        y ^= y << 5;
        y ^= y >>> 7;
        y ^= y << 22;
        t = z + w + c;
        z = w;
        c = (t < 0) ? 1 : 0;
        w = t & 2147483647;
        x += 1411392427;
        return x + y + w;
    }
}

class RngTest {
    public static void main(String[] s) {
        for (int i = 0; i < 20; ++i)
            System.out.format("%11d\n", JKISS.jkiss32());
    }
}
which you can run with java RngTest (after compiling this) from the console.
 
  • #21
wle, you're my shining knight :kiss:

Brilliant! Exact match. Even brillianter is that I just ran the output through ENT (Fourmilab) and got...

Code:
C:\scratch>ent jkiss32-1gb.bin
Entropy = 8.000000 bits per byte.

Optimum compression would reduce the size
of this 1000000000 byte file by 0 percent.

Chi square distribution for 1000000000 samples is 266.30, and randomly
would exceed this value 30.07 percent of the times.

Arithmetic mean value of data bytes is 127.5008 (127.5 = random).
Monte Carlo value for Pi is 3.141699301 (error 0.00 percent).
Serial correlation coefficient is -0.000009 (totally uncorrelated = 0.0).

Looks pretty good eh? I've attached a picture of the JKISS output I know readers are dying to see. Thanks again.

I've got the main() thing covered. I only presented the code in this fashion for brevity.
 

Attachments

  • jkiss32-1gb.png
    jkiss32-1gb.png
    198.4 KB · Views: 500
  • #22
I really structure it as:-

Code:
public class JKISS32 {

    private int x = 123456789, y = 234567891, z = 345678912, w = 456789123, c = 0, t;    public JKISS32() {
    }    public int nextInt() {
        y ^= (y << 5);
        y ^= (y >>> 7);                    // One > added from PF
        y ^= (y << 22);
        t = z + w + c;
        z = w;
        c = (t < 0) ? 1 : 0;               // 1 or 0 ammendment from PF
        w = t & 2147483647;
        x += 1411392427;
        int next = x + y + w;
        return next;
    }
}

and test as:-

Code:
    @Test
    public void testRNG() {
        System.out.println("Default run");
        JKISS32 jk = new JKISS32();        for (int i = 0; i < 20; i++) {
            System.out.println(jk.nextInt());
        }        assertTrue(true);
    }
 

1. What does the "c" stand for in c = t < 0?

The "c" in this equation stands for a constant or a variable that represents a value.

2. What is the significance of using "t" in this equation?

The "t" in this equation typically stands for time. This means that the equation is likely related to a measurement or calculation involving time.

3. What does the less than symbol "<" indicate in this equation?

The less than symbol indicates a comparison being made between two values. In this case, the equation is stating that the value of "t" is less than zero.

4. Why is the equation written in C language?

C is a widely used programming language in scientific and mathematical fields due to its efficiency and versatility in handling numerical calculations.

5. What is the significance of the "0" in this equation?

The "0" in this equation is a specific value that is being compared to the value of "t". It could represent a starting point, a baseline, or a threshold value depending on the context of the equation.

Similar threads

  • Programming and Computer Science
Replies
2
Views
1K
Replies
9
Views
1K
  • Programming and Computer Science
Replies
5
Views
2K
  • Programming and Computer Science
Replies
31
Views
2K
  • Programming and Computer Science
Replies
8
Views
878
  • Programming and Computer Science
Replies
3
Views
680
  • Programming and Computer Science
Replies
1
Views
729
  • Programming and Computer Science
Replies
3
Views
3K
  • Programming and Computer Science
Replies
6
Views
991
  • Special and General Relativity
4
Replies
123
Views
5K
Back
Top