From C to Julia: Notes from a low-level port

I ported bit-shifting math from C to Julia and thought I would share notes on gotchas.

Simple changes in operators

  • Division - The solidus character, /, becomes div in Julia, ÷. The / in Julia is floating-point division, so it will promote integers to reals.
  • Exclusive or - The caret character, ^, becomes the xor symbol, . The ^ in Julia is exponentiation.

Both of these operators are will compile fine but have different meaning, so they are easy to mis-type and not notice.

For-loops change scope and increment

In C, the variable j exists after the loop.

	for (j = 1; j < DIM; j++)
		if ((P >> j & 1) == (P & 1))
			continue;
		else
			break;
	if (j != DIM)
		J -= j;

In Julia, for-loops have a new scope for the loop variable.

j = -1
for j = 1:3
    println(j)
end
println(j)

This will print 1, 2, 3, -1. We can rewrite the for-loop as a while-loop, which is generally handy when C for-loops do lots of initialization and increments.

j = 1
while j < DIM
	if ((P >> j & one(P)) == (P & one(P)))
		j += 1
	else
		break
end
if j != DIM
    J -= j
end

Operator precedence changes

C and Julia group mathematical operations differently. They put implicit parentheses in different places. For instance, this small expression means something different in both languages.

temp2 = S << DIM - xJ % DIM;

The operator precedence in C is 1. %, 2. -, 3. <<, 4. =.
In Julia, it’s 1. <<, 2. %, 3. -, 4. =. We could put in all of the parentheses, or just those we need.

temp2 = S << (DIM - xJ % DIM)

Maybe we can look at a few operators, listed from high precedence to low, left-to-right, to pick out differences.

C precedence for select operators.
(* / %) (+ -) (<< >>) (< <= > >=) (== !=) (&) (^) (|)  (&&) (||) (= += -= <<= >>= &=)
(<< >>) (* / %) (& ÷) (+ - | ⊻) (> < >= <=) (== !=)    (&&) (||) (= += -= &= <<= >>=)
Julia precedence for select operators.

The bit-shifting operators move above addition and subtraction. The XOR and AND operators move above greater-than and less-than. In general, it’s good to double-check the C precedence.

HTH!

6 Likes

I may be missing something here, but both julia and C have % as the modulus operator, don’t they? :thinking: (or rather, the remainder of division)

1 Like

Ah! You’re so right. I meant “solidus,” which is the name of the forward-slash. That’s what I get for trying to be fancy. They do both have the modulus, and it means the same thing in both. Thank you!

1 Like

You’re welcome! :slight_smile:

There was a great article about why the operator precedence in C between & and && is the way it is (historical reasons older than grep), but I can’t seem to find it anymore :confused:

Edit: Found it!

2 Likes

You can have the C behavior with the outer keyword:

1 Like

Very nice! I think you might have a couple of points that aren’t made in Noteworthy differences from C/C++. It might be good to add a line or two there as hopefully that’s the place folks will end up if they’re porting between C and Julia.

It’s also worth noting that because it’s easy to make a .dll or .so file, and ccall is easy to use, one can test both versions with the same tests. I’ve done a little bit of this, making some algorithm in Julia, then porting it to C.

4 Likes

That C/C++ comparison seems complete, really, and very helpful, as is using ccall. And you’re porting to C? Sure, there are good cases for that, aren’t there.

I’m doing simulations and designing control laws which ultimately get implemented in microcontrollers (or in some cases FPGAs), so it’s not like a general case of porting Julia to C. It would be more correct to say that I’m writing algorithms with relatively simple math and logical constructs knowing I won’t even have floating point hardware to use in the end.

1 Like