Is there a difference between these two operations? [closed] - c

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I would like to ask if there is a difference in the result (s16Result) between
int16_t s16X, s16Y, s16Result;
s16Result = (int16_t) (s16X - s16Y);
and
int16_t s16X, s16Y, s16Result;
s16Result = (int16_t) ((uint16_t) s16X - (uint16_t) s16Y)
with s16X and s16Y having the datatype signed integer and therefore having the range -32767...32767 . Thank you.

These statements do not generally have the same behavior as defined by the C standard. Consider when s16X has the least value of its type (e.g., perhaps INT_MIN in an implementation where the int type is 16 bits, so it could be −32767) and s16Y is 2. Then, in:
s16Result = (T_S16) (s16X - s16Y)
the expression s16X - s16Y overflows—the mathematical result of −32769 is not representable in the int type, and the C standard does not define the result.
However, in:
s16Result = (T_S16) ((T_U16) s16X - (T_U16) s16Y)
the T_U16 type is presumably an unsigned 16-bit type. In this case, s16X is converted to the 16-bit type by adding or subtracting 65536, yielding 32769. s16Y retains its value of 2. Then the subtraction yields 32767. finally, this result is converted to the T_S16 type, which keeps the value 32767.
Thus, the statement with unsigned arithmetic may have a defined value in some situations where the statement with signed arithmetic does not have a value defined by the C standard.
(The statement with unsigned arithmetic still has undefined behavior if the final result is not representable in the T_S16 type, as when the final result is a number from 32768 to 65535 rather than from 0 to 32767.)

Related

How can I merge two ASCII characters? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I want to merge two characters and print them via a single variable by using ASCII (refer to the image below):
[1]: https://i.stack.imgur.com/TWodP.jpg
try this if your machine is little endian
unsigned int C = (b << 8) | a;
printf("%s",&C);
otherwise if your machine is big endian try
unsigned int C = (a << 24) | (b<<16);
printf("%s",&C);
Based on my comment, but improved by Jonathan's input, I propose to do this:
int C;
C= (((unsigned char)a)<<8)|((unsigned char)b);
You have already tried the commented version to be helpful, this one is basically the same, just being robust against potentially negative values of a and b (which I considered out of scope, but Jonathan is right in being as safe as possible).
As for the explanation:
The << 8 part, a so-called bitshift left, moves a value by 8 bit towards the MSBs.
I.e. a 00000000010000001 becomes a 01000000100000000.
To be safe from negative value (see below why that is important), the value is first type-casted to unsigned char. That is the part ((unsigned char)a). Note that I tend to be generous when it comes to using (), some people do not like that. This is done for both values.
With values 'A' and 'B' we end up with
0100000100000000 and
0000000001000010.
The next part uses a bitwise OR (|), in contrast to a logical OR (||).
The result is
0100000101000010, which is what I understand to be your goal.
The importance of protecting against negative input is this. Any negative 8bit value has the MSB set and when cast to a wider data type will end up with all 8 new high bits set. This is because of the representation of negative values in integers in 2-compliment.
The final conversion to the desired wider data type is as Jonathan explains:
If you have (unsigned char)A << 8 as a term, then the unsigned char value is extended to int before the shift occurs, and the result is an int.

C Binary Operator & (-1) [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
Suppose you have code including:
if(i & (-1)) {}
Depending on i, what would this operation return?
There's no definitive answer to this question: it depends on the type of i and, if the operation is performed in the domain of signed type, on the signed representation used by the given platform.
For example, if i is of type unsigned int (or some larger unsigned type), the entire operation will be performed in the domain of that unsigned type. In that case -1 will get implicitly converted (by usual arithmetic conversions) to all-ones bit pattern as wide as i. The whole if will effectively become equivalent to if (i).
But with i of signed type - there's no way to say anyhting for certain.
The results of performing a bitwise operation on a negative value are implementation defined.
For example, if 2's complement representation is used for negatives, the value -1 will be represented by a sequence of all 1 bits, so performing a bitwise AND with -1 will result in the value of i.
On the other hand, if sign magnitude representation is used, only 2 bits are set in the value -1, the highest and the lowest. In that case, only the highest and lowest bits of i (after any conversions) will be set in the result.
So to summarize, you can't depend on the results without some implementation defined method of determining the representation of negative values.

right shifting the double variable [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
hi I want to do the followed task:
double time;
char array[6];
for(int index=0; index<6; index++){
array[index]=(char)(time>>(8*index));
}
but the error appears: expresion must have integral or unscoped enum
From ISO/IEC 9899:1999 (a.k.a. C99 standard):
6.5.7 Bitwise shift operators
Constraints
2 Each of the operands shall have integer type.
If you want to divide time by 2 to the power of (8*index), you can either:
Use pow() from math.h, or
Create an integer variable with value 1 << (8*index), then divide time by this variable
If you want to actually do a bit shift of the binary representation of the IEEE floating point number(1) (not that I understand why you would want to do that), you can do the following:
uint64_t x = *(uint64_t *)&time;
array[index]=(char)(x>>(8*index));
(1): Assuming your implementation uses IEEE floating point
Right shifting a float or double is almost certainly not what you meant to do, as the data representation is not one that would be affected by right shift as division by a power of 2.
You cannot use right-shifting operator for double variable.

Regarding bitwise shift operator in C [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
According to text:
"In rare case of C/C++ compiler that does not perform sign extension on right shift of a negative number, the trick to shift right to divide the number fails"
Consider the following example:
unsigned int i = 0b10000000; // 128
i = i >> 1; // i equals 01000000 i.e. 64
That is the only way I know to block sign extension. Also, by adding unsigned it becomes a positive number so please correct.
Sign extension on bitwise right-shift of negative number is implementation-defined in C. It means it is up to the compiler to decide if it performs the sign propagation and the compiler documentation has to document the selected behavior.
From the C Standard:
(C99, 6.5.7) "If E1 has a signed type and a negative value, the resulting value is implementation-defined."
Among compilers, gcc always propagates the sign:
Signed `>>' acts on negative numbers by sign extension.
http://gcc.gnu.org/onlinedocs/gcc/Integers-implementation.html

Am I nuts or did I find an issue with C's design? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
Ok, so fgetc() returns an unsigned char cast to int, and EOF at... EOF. What if you're trying to read in a config file to a char array, and your implementation's char is signed? The standard for C99 says that not only is the result implementation-defined to assign an unrepresentable value to a signed variable, but that the implementation can alternatively choose to raise a signal instead!
6.3.1.3 Signed and unsigned integers
When a value with integer type is converted to another integer type other than _Bool, if the value can be represented by the new type, it is unchanged.
Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type.49)
Otherwise, the new type is signed and the value cannot be represented in it; either the result is implementation-defined or an implementation-defined signal is raised.
Constructs like this are very common:
int c, i = 0;
char arr[1024];
for (; (c = getc(Descriptor)) != EOF && i < sizeof arr - 1; ++i)
{
arr[i] = (char)c;
}
arr[i] = '\0';
It's also implementation-defined to perform the cast if char is signed and the value in c is higher than can be represented.
I find it extremely unlikely that I have found a problem that thousands of programmers have missed over the years, especially with the ubiquitousness of the construct above.
It seems that there is a possibility that non-text code read through this means could cause issues, since some of the bytes could have values that don't fit in a signed char.
I've never seen a modified version of the above construct that actually addresses this put to use.
Have I actually found a flaw relating to the C standard, or noticed something thousands of other programmers have not and failed to implement in their error checking?

Resources