How is a multi-char variable of type char (and not char array) is processed in C? - char

I tried this
#include<stdio.h>
int main(void){
char charVal1 = '1';
char charVal2 = '91';
printf("%d\n", charVal1);
printf("%d", charVal2);
}
The output of the first printf statement is 49. But the other one is showing 14641. How 91 is converted into 14641? Also, sometimes it shows that the implicit conversion resulted in overflow and the output is 49.

In your system, the character '1' is encoded as 49. C requires that the characters '1'…'9' be in that order and contiguous so on your system '9' is encoded as 57. So, '91' is encoded as 57 followed by 49. In hexadecimal, this 0x39 followed by 0x31. If you consider that two-byte integer (possibly a short [aka short int] on your system) with the big-endian byte ordering, it is 0x3931 or 14641. So your machine uses the big-endian byte ordering.
'91' is an int with a value 14641. On my system, int is bigger than char and char is -128 to 128 so assigning a char with an integer outside that range, gives a compiler warning.
Now your formatted print call uses the "%d" format specifier, which is for normal length integers. This means that it will convert however many bytes an integer is on your system to decimal and output that. But, you are passing it char values so it is printing those values as integers, or 91 and 14641.
You probably mean something more like this:
char[] strVal1 = "1";
char[] strVal2 = "91";
printf("%s\n", strVal1);
printf("%s", strVal2);

Related

substraction : replace blank with zero

// this is a substraction example
int x=3098;
int z=3088;
int somme=x-z;
char buffer[4];
// convert int to char
itoa(somme,buffer,10);
// I want to push the buffer value on a char table like this "**0010**" not
// like "**10**"
Then you have to use a formater, standard ones in C are of printf family. Take care of the length of the array because if you want to store a string of length n you need an array of length n+1 (c-strings are Null-terminated). Thus:
// this is a substraction example
int x=3098;
int z=3088;
int somme=x-z;
char buffer[5];
sprintf(buffer,"%04d",somme);
will fit your needs. It means to format the integer somme as (%04d) decimal representation of length 4 padded with leading zeros if needed, and to store the result in memory starting at the beginning of buffer.

How to convert std::string to std::u32string?

Is there an easy STL way to convert a std::string to a std::u32string, i.e. a basic_string of char to char32_t?
This is not a Unicode question.
To initialise a new string:
std::u32string s32(s.begin(), s.end());
To assign to an existing string:
s32.assign(s.begin(), s.end());
If the string might contain characters outside the supported range of char, then this might cause sign-extension issues, converting negative values into large positive values. Dealing with that possibility is messier; you'll have to convert to unsigned char before widening the value.
s32.resize(s.size());
std::transform(s.begin(), s.end(), s32.begin(),
[](char c) -> unsigned char {return c;});
or a plain loop
s32.clear(); // if not already empty
for (unsigned char c : s) {s32 += c;}
s32.resize(s.length());
std::copy(s.begin(),s.end(),s32.begin());

long double subnormals/denormals get truncated to 0 [-Woverflow]

In the IEEE754 standarad, the minimum strictly positive (subnormal) value is 2−16493 ≈ 10−4965 using Quadruple-precision floating-point format. Why does GCC reject anything lower than 10-4949? I'm looking for an explanation of the different things that could be going on underneath which determine the limit to be 10-4949 rather than 10−4965.
#include <stdio.h>
void prt_ldbl(long double decker) {
unsigned char * desmond = (unsigned char *) & decker;
int i;
for (i = 0; i < sizeof (decker); i++) {
printf ("%02X ", desmond[i]);
}
printf ("\n");
}
int main()
{
long double x = 1e-4955L;
prt_ldbl(x);
}
I'm using GNU GCC version 4.8.1 online - not sure which architecture it's running on (which I realize may be the culprit). Please feel free to post your findings from different architectures.
Your long double type may not be(*) quadruple-precision. It may simply be the 387 80-bit extended-double format. This format has the same number of bits for the exponent as quad-precision, but many fewer significand bits, so the minimum value that would be representable in it sounds about right (2-16445)
(*) Your long double is likely not to be quad-precision, because no processor implements quad-precision in hardware. The compiler can always implement quad-precision in software, but it is much more likely to map long double to double-precision, to extended-double or to double-double.
The smallest 80-bit long double is around 2-16382 - 63 ~= 10-4951, not 2-164934. So the compiler is entirely correct; your number is smaller than the smallest subnormal.

Character range in Java

I've read in a book:
..characters are just 16-bit unsigned integers under the hood. That means you can assign a number literal, assuming it will fit into the unsigned 16-bit range (65535 or less).
It gives me the impression that I can assign integers to characters as long as it's within the 16-bit range.
But how come I can do this:
char c = (char) 80000; //80000 is beyond 65535.
I'm aware the cast did the magic. But what exactly happened behind the scenes?
Looks like it's using the int value mod 65536. The following code:
int i = 97 + 65536;
char c = (char)i;
System.out.println(c);
System.out.println(i % 65536);
char d = 'a';
int n = (int)d;
System.out.println(n);
Prints out 'a' and then '97' twice (a is char 97 in ascii).

Char conversion in gcc

What are the char implicit typecasting rules? The following code gives an awkward output of -172.
char x = 200;
char y = 140;
printf("%d", x+y);
My guess is that being signed, x is casted into 72, and y is casted into 12, which should give 84 as the answer, which however is not the case as mentioned above. I am using gcc on Ubuntu.
The following code gives an awkward output of -172.
The behavior of an overflow is implementation dependent, but visibly in your case (and mine) a char has 8 bits and its representation is the complement by 2. So the binary representation of the unsigned char 200 and 140 are 11001000 and 10001100, corresponding to the binary representation of the  signed char -56 and -116, and -56 + -116 equals -172 (the char are promoted to int to do the addition).
Example forcing x and y to be signed whatever the default for char:
#include <stdio.h>
int main()
{
signed char x = 200;
signed char y = 140;
printf("%d %d %d\n", x, y, x+y);
return 0;
}
Compilation and execution :
pi#raspberrypi:/tmp $ gcc -Wall c.c
pi#raspberrypi:/tmp $ ./a.out
-56 -116 -172
pi#raspberrypi:/tmp $
My guess is that being signed, x is casted into 72, and y is casted into 12
You supposed the higher bit is removed (11001000 -> 1001000 and 10001100 -> 1100) but this is not the case, contrarily to the IEEE floats using a bit for the sign.

Resources