In some cases, NULL values are reported as 0 (zero)

I noticed that in some cases, NULL values are reported as 0 (zero). Please look at the output of the following script, this line:
bb = 0;

xx = SelectedValue(BarIndex());

aa = Null;
printf( "aa[xx] = " + aa[xx] + "\n" );
printf( "aa = " + aa + "\n" );
printf( "NumToStr(aa,8.3)  = " + NumToStr(aa,8.3) + "\n" );

bb = Null;
bb[BarCount-2]= H[BarCount-2];
printf( "bb[xx] = " + bb[xx] + "\n" );
printf( "bb = " + bb + "\n" );  // prints ZERO, not NULL
printf( "NumToStr(bb,8.3)  = " + NumToStr(bb,8.3) + "\n" );

output:

aa[xx] = {EMPTY}
aa = {EMPTY}
NumToStr(aa,8.3)  = {EMPTY}
bb[xx] = {EMPTY}
bb = 0
NumToStr(bb,8.3)  = {EMPTY}

The entire aa array is NULL, it does not happen there. Array bb is also NULL, except just one cell. And then all the NULL cells are reported as ZERO when I use :

printf( "bb = " + bb + "\n" );

Am I doing something wrong?

Don't plainly compare aa and bb.

on bb, you have performed this operation bb[BarCount-2]= H[BarCount-2]; which changes its characteristic.

Also, I prefer using TRACEF() because printf() is meant for interpretation and may modify output for readability, like Null shown as {EMPTY}
TRACEF() will give you raw values.
bb = 0 in trace for me gives AB NULL that's currently -1e+10

Also, AFL does internal type casting, but that doesn't mean a user can write reckless code.

aa = Null;
printf( "aa[xx] = " + aa[xx] + "\n" );

You are defining aa as a scalar variable and in the immediate next line, you are accessing it as a Vector(Array).
C'mon :stuck_out_tongue: where's the correct logic in it ?

I haven't given you an answer, TJ only knows the inner mechanics, but correct programming practices have to be followed for consistent results.

2 Likes

@travick

You are 100% right. The debugger correctly reported the values as NULL. The printf changed the result.

1 Like

printf() does not change anything. The effect that you see is due to the way how you wrote your code. In your code you are adding string to numerical array:

"bb = " + bb + "\n"; // where bb is a numerical array with Nulls

Despite innocent look 'plus' operator has different semantics depending on type of arguments. And you've got incompatible types here. For strings 'plus' means concatenate, for numbers it has mathematical meaning so if you write such code, AmiBroker must run some circles to make it possible. To do so it has to take SelectedValue() of array bb and convert it to string and then concatenate it with remaining strings.

But SelectedValue() the same way as LastValue() converts all Nulls to zero. You can check this:

x = SelectedValue( Null ); // x will be 0

That is why when you add a string to ARRAY filled with Nulls you will get them treated as zero.

Proper way to use printf() to print the numerical value is

printf("value is = %g\n", bb );

This will give you -1e10 for Nulls. Why? Because you are NOT adding string to numerical array here.

First string is a formatting string. It gets interpreted by printf(). Values should come afterwards. It is much faster and safer than "adding" strings to numerical arrays the way you do. If first string in printf() has any special characters like % it would get interpreted as formatting command and in case of absence of matching arguments would result in runtime errors. For these reasons, formatting string in printf() should be constant literal.

More read about types and coercion:

3 Likes

@Tomasz, thank you for the very detailed explanation.

I only use printf for quick debugging. I should have known better.