בעיה מוזרה ב c

alexrait1

New member
בעיה מוזרה ב c

כמראה שאני מפספס פה משהו, אבל הקוד הזה לא עובד לי:
include<stdio.h> int main(){ int z=-2000; unsigned int j=2,i=2000; if (z-i*j< -5000.0){ printf("works"); } }​
 

annefan

New member
תראה

#include<iostream> using namespace std; int main(){ int z=-2000; unsigned int j=2,i=2000; cout << (z-i*j) << endl; if ((z-i*j)< -5000.0){ printf("works\n"); } else printf("Not\n"); return 0; }​
הפכתי את זה ל-++C כדי שאוכל להשתמש ב-cout, אבל השאר אותו דבר. מעניין, נכון?
 

ahab

New member
מה לא עובד?

חוץ מזה שחסר # ב-include, מה לא עובד פה...
 

ahab

New member
למה אתה חושב שזה צריך להדפיס works?

i*j - חישוב ב-unsigned int - התוצאה 4000 (unsigned int). z-i*j - חישוב ב-unsigned int (יש המרה של z ל-unsigned) - התוצאה 4294961296 (unsigned int). 5000.0- - זה מטיפוס double, ולכן גם התוצאה הקודמת תומר ל-double לפני ביצוע ההשוואה. ואכן, 4294961296.0 > 5000.0-. זה אחרי בדיקה זריזה עם gcc. פיספסתי משהו?
 

alexrait1

New member
זאת השאלה

מה סדר ההמרה int->unsigned int או הפוך... איזה טיפוס יותר כולל...
 

ahab

New member
וזאת התשובה...

Many operators cause conversions and yield result types in a similar way. The effect is to bring operands into a common type, which is also the type of the result. This pattern is called the usual arithmetic conversions. • First, if either operand is long double, the other is converted to long double. • Otherwise, if either operand is double, the other is converted to double. • Otherwise, if either operand is float, the other is converted to float. • Otherwise, the integral promotions are performed on both operands; then, if either operand is unsigned long int, the other is converted to unsigned long int. • Otherwise, if one operand is long int and the other is unsigned int, the effect depends on whether a long int can represent all values of an unsigned int; if so, the unsigned int operand is converted to long int; if not, both are converted to unsigned long int. • Otherwise, if one operand is long int, the other is converted to long int. • Otherwise, if either operand is unsigned int, the other is converted to unsigned int. • Otherwise, both operands have type int.​
מתוך The C Programming Language. או בקיצור, ההמרה היא לטיפוס unsigned. :)
 
עכשיו זה עובד...

תוסיף סוגריים...גם עוזר בקריאה, גם מסדר את הקוד.
#include<stdio.h> int main() { int z=-2000; unsigned int j=2,i=2000; if (z-(i*j)< (-5000)) { printf("works"); } }​
 

alexrait1

New member
אתה צוחק?

כל הרעיון שלא יהיה כתוב -5000 אלא -5000.0 זאת הבעיה כאן. דרך אגב, תנסו להדפיס סתם z-i....
 
צוחק מי שצוחק אחרון...

עכשיו זה עובד עם הנקודה.
#include<stdio.h> int main() { float z=-2000; unsigned int j=2,i=2000; if (z-(i*j)< (-5000.0)) { printf("works"); } }​
 

alexrait1

New member
אני לא מחפש פתרונות כאלו

שינית את z להיות float.... אני רק רוצה להבין מה הולך פה
 

alexrait1

New member
הרצתי אותה אצלי וזה לא עובד

אולי כי אני משתמש ב gcc או ב g++? (אין לי משהו אחר על הלינוקס..)
 

annefan

New member
לא חשוב, כבר קיבלת תשובה

(אגב גם אני הרצתי ב-++g, אבל לא חשוב). הכלל ב-++C אומר שכשי ביטוי בו אחד מהאופרנדים הוא unsigned, האופרנד השני הופך גם הוא לכזה. לכן אצלך: i*j -> שניהם unsigned, ממילא התוצאה גם כזו. z-i*j -> הביטוי i*j הוא unsigned, ולכן גם z מומר אליו, וכך תוצאת כל הביטוי. כיוון שהביטוי הוא unsinged הוא בהכרח גדול מ-0, ובפרט גדול מ--5000.
 
למעלה