473,385 Members | 1,548 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

printf anomaly

Hi experts

Consider this piece of code

unsigned long data = 124; /* Data is actually part of a big struct but
to simplify */
printf(" %-5llu ", (unsigned long long)(data*1000));
<memory address say 60000000>: 00000000 00000D77 00000000
00000000
0xD77 is 3447

Assume data is at the beginning of memory address 60000000 and this is
a big endian machine (MIPS based).
The compiler is doing two load word from 60000000 and 60000000+4 and
then multiplying it by 1000 and then prints 3447000 which is not
expected.

My understanding is that the 1000 will default to int
Then it will be promoted to unsigned long (since on our platform long
and int are of same size)
then operation will be carried out in unsigned long (result I mean).
then *result* will be cast to unsigned long long and then it will be
passed to printf
(not sure how - this is MIPS based platform) and printf is a variadic
function.

I must be missing something or the compiler is broken?

1.Please help me understand what is going on.
2.And how can I fix it the right way.

Please advise.
Thanks in advance,

Feb 22 '07 #1
10 1862
unsigned long data = 0x124
please ignore the above initialization line in previous post.
I only wanted to say : the type of data is unsigned long.
Thanks

Feb 22 '07 #2
in*******@yahoo.com wrote:
>
unsigned long data = 0x124

please ignore the above initialization line in previous post.
That line wasn't in your previous post.
I only wanted to say : the type of data is unsigned long.
You do need to say more than the type of the data.
The nature of your complaint is the output of printf,
which also depends on the value of data.

Create and post the smallest program that still exhibits your problem.
Try to use copy and paste facilities or something equivalent,
instead of posting you recollections
of what the code may have looked like.

--
pete
Feb 22 '07 #3
in*******@yahoo.com writes:
Consider this piece of code

unsigned long data = 124; /* Data is actually part of a big struct but
to simplify */
printf(" %-5llu ", (unsigned long long)(data*1000));
<memory address say 60000000>: 00000000 00000D77 00000000
00000000
0xD77 is 3447

Assume data is at the beginning of memory address 60000000 and this is
a big endian machine (MIPS based).
The compiler is doing two load word from 60000000 and 60000000+4 and
then multiplying it by 1000 and then prints 3447000 which is not
expected.

My understanding is that the 1000 will default to int
Then it will be promoted to unsigned long (since on our platform long
and int are of same size)
then operation will be carried out in unsigned long (result I mean).
then *result* will be cast to unsigned long long and then it will be
passed to printf
(not sure how - this is MIPS based platform) and printf is a variadic
function.

I must be missing something or the compiler is broken?
In a followup you wrote:
| unsigned long data = 0x124
|
| please ignore the above initialization line in previous post.
| I only wanted to say : the type of data is unsigned long.

But in your original post, data was initialized to 124, not 0x124.
The fact that you misquoted your own post doesn't fill me with
confidence that you've shown us your actual code and data. You show a
printf call with a format of "%-5llu", but your output is in
hexadecimal with leading zeros.

I can't tell from what you posted what the problem might be. Post a
small complete program that exhibits the problem, along with the
actual output and what you expected the output to be. Don't re-type
either the program or the output; copy-and-paste it exactly.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Feb 22 '07 #4
Pete,

Sure, let me try again.

printf(" %-5llu ", (unsigned long long)(data*1000));

<16 byts of memory starting at 0x60000000 in hex>:
00000000 00000D77 00000000 00000000

data is a unsigned long 4 byte variable starting at 0x60000000
This is a big endian cpu and address is incrementing for the above
memory dump.
0xD77 is 3447 in decimal.

The output printed is 3447000 in decimal and expected output is zero.
I would like to understand what is happening.

Thank you,
-Sushil

Feb 22 '07 #5
But in your original post, data was initialized to 124, not 0x124.
The fact that you misquoted your own post doesn't fill me with
confidence that you've shown us your actual code and data. You show a
printf call with a format of "%-5llu", but your output is in
hexadecimal with leading zeros.

Keith,

This is running on an embedded system and I can not copy the output.
What I pasted was dump of memory as seen from a debugger, not a
printed output.

Thanks for the reply,
Feb 22 '07 #6
in*******@yahoo.com wrote:
>
Pete,

Sure, let me try again.

printf(" %-5llu ", (unsigned long long)(data*1000));

<16 byts of memory starting at 0x60000000 in hex>:
00000000 00000D77 00000000 00000000

data is a unsigned long 4 byte variable starting at 0x60000000
This is a big endian cpu and address is incrementing for the above
memory dump.
0xD77 is 3447 in decimal.

The output printed is 3447000 in decimal and expected output is zero.
I would like to understand what is happening.
Post a complete program.

--
pete
Feb 22 '07 #7
in*******@yahoo.com wrote, On 22/02/07 02:21:
>But in your original post, data was initialized to 124, not 0x124.
The fact that you misquoted your own post doesn't fill me with
confidence that you've shown us your actual code and data. You show a
printf call with a format of "%-5llu", but your output is in
hexadecimal with leading zeros.


Keith,

This is running on an embedded system and I can not copy the output.
You can copy and paste the program which evidence suggests you did not do.
What I pasted was dump of memory as seen from a debugger, not a
printed output.
Anything could be going on in memory. All we can comment on is what the
output of the printf call should be on a hosted implementation (if it is
not hosted it is not even required to provide printf), and then only if
we are given a *complete* compilable program.
--
Flash Gordon
Feb 22 '07 #8
On 21 Feb 2007 17:24:14 -0800, in*******@yahoo.com wrote in
comp.lang.c:
Hi experts

Consider this piece of code

unsigned long data = 124; /* Data is actually part of a big struct but
to simplify */
I understand that in a later post you day that the initialization line
above is not correct, and to just assume that you meant to define
"data" as having the type unsigned long.

Unfortunately, in your later post and replies to other respondents you
do not leave enough context to add additional replies.
printf(" %-5llu ", (unsigned long long)(data*1000));
<memory address say 60000000>: 00000000 00000D77 00000000
00000000
0xD77 is 3447
I have no idea what this means, memory dumps are not relevant.
Assume data is at the beginning of memory address 60000000 and this is
a big endian machine (MIPS based).
Why should I assume that? You appear to assume that, and because of
that you assume that the compiler is doing something wrong.
The compiler is doing two load word from 60000000 and 60000000+4 and
then multiplying it by 1000 and then prints 3447000 which is not
expected.
How the compiler chooses to access the contents of lvalues is up to
the compiler. If you are sure it is incorrect you need to contact the
compiler supplier.
My understanding is that the 1000 will default to int
Then it will be promoted to unsigned long (since on our platform long
and int are of same size)
Your understanding is wrong. The type of the integer literal
expression "1000" is int, no default involved. You are also wrong in
thinking that the sizes of int and long have anything to do with the
automatic conversion. When you perform an operation on a signed int
and an unsigned long, the signed int value will be converted to
unsigned long regardless of whether the sizes are the same or
different.
then operation will be carried out in unsigned long (result I mean).
then *result* will be cast to unsigned long long and then it will be
passed to printf
So exactly what are you concerned about? 1000UL * 3447UL = 3447000UL,
which is a value that clearly fits in an unsigned long. The cast
operator converts this unsigned long long, in which it will surely fit
and have the same value.
(not sure how - this is MIPS based platform) and printf is a variadic
function.

I must be missing something or the compiler is broken?
We're missing something, namely the information that you did not
provide. Don't show us a hexadecimal dump of what you think is the
relevant part of memory, that is irreverent.

Are you claiming that the value of "data" is not 3447? How do you
know?

Show us the output of this code:

printf("%lu", data);
printf("%llu", (unsigned long long)(data*1000))

1.Please help me understand what is going on.
2.And how can I fix it the right way.
Even better, show us the structure definition and how the object is
actually accessed in the code, without the simplification.

I have seen cases where an access to a structure member actually
access the wrong bytes of the object. This is most common when people
play games with pointers and make mistakes or have incorrect
assumptions, but there are other possible causes.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Feb 22 '07 #9
in*******@yahoo.com wrote:
Consider this piece of code

unsigned long data = 124; /* Data is actually part of a big struct but
to simplify */
printf(" %-5llu ", (unsigned long long)(data*1000));

<memory address say 60000000>: 00000000 00000D77 00000000
00000000
0xD77 is 3447

Assume data is at the beginning of memory address 60000000 and this is
a big endian machine (MIPS based).
The compiler is doing two load word from 60000000 and 60000000+4 and
then multiplying it by 1000 and then prints 3447000 which is not
expected.

My understanding is that the 1000 will default to int
Then it will be promoted to unsigned long (since on our platform long
and int are of same size)
then operation will be carried out in unsigned long (result I mean).
then *result* will be cast to unsigned long long and then it will be
passed to printf
(not sure how - this is MIPS based platform) and printf is a variadic
function.

I must be missing something or the compiler is broken?

1.Please help me understand what is going on.
What you are missing could be the knowledge that sizeof (unsigned long)
is 8.
2.And how can I fix it the right way.
There would be nothing wrong and nothing to fix.

--
DPS
Feb 22 '07 #10
in*******@yahoo.com wrote:
Pete,

Sure, let me try again.

printf(" %-5llu ", (unsigned long long)(data*1000));

<16 byts of memory starting at 0x60000000 in hex>:
00000000 00000D77 00000000 00000000

data is a unsigned long 4 byte variable starting at 0x60000000
This is a big endian cpu and address is incrementing for the above
memory dump.
0xD77 is 3447 in decimal.

The output printed is 3447000 in decimal and expected output is zero.
I would like to understand what is happening.
So data occupies 8 bytes. 0x0000000000000d77 which is 3447 and when
multiplied by 1000 yields 3447000. What's the problem?

--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Feb 23 '07 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

11
by: Grumble | last post by:
Hello, I have the following structure: struct foo { char *format; /* format string to be used with printf() */ int nparm; /* number of %d specifiers in the format string */ /* 0 <= nparm <=...
8
by: aditya | last post by:
hi, Can anybody please tell me that how the following printf(...) statement works- main(){ int d=9; printf("%d",printf("%d")); return 0;
7
by: teachtiro | last post by:
Hi, 'C' says \ is the escape character to be used when characters are to be interpreted in an uncommon sense, e.g. \t usage in printf(), but for printing % through printf(), i have read that %%...
16
by: clintonG | last post by:
At design-time the application just decides to go boom claiming it can't find a dll. This occurs sporadically. Doing a simple edit in the HTML for example and then viewing the application has...
4
by: pai | last post by:
Hi , Can any one tell me how this statement of printf is behaving . how the last digit is printed int a=2,b=4,c=7; printf("%d",printf("%d %d:",a,b)); //answer to this was 2 4:3
11
by: timmu | last post by:
Someone asked me a question about integer division and printf yesterday, I tell him he should do a casting to float/double before you do any interger division. But he doesn't think so, so I try...
34
by: Old Wolf | last post by:
Is there any possible situation for printf where %hd causes a different result to %d, and the corresponding argument was of type 'short int' ?
1
by: mai | last post by:
Hi everyone, i'm trying to exhibit FIFO anomaly(page replacement algorithm),, I searched over 2000 random strings but i couldnt find any anomaly,, am i I doing it right?,, Please help,,,The...
1
by: linq936 | last post by:
Hi, I read in many places that the string to be outputted by printf() must be ending with newline, for example, it should be printf("Hello World.\n"); instead of printf("Hello World.");
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.