Qanday qilib, int ichida C int sifatida chetga surilishni yumalaymiz

Men kollejdagi ikkinchi semestrning birinchi kursdoshiman. Ustozimiz, bizga yuz ellikka yaqin suzuvchi nuqta atrofidagi funksiyani yozishni talab qiladi. U suzuvchi nuqtani tamsaytli ma'lumotlar turiga aylantirishi va keyin uni suzuvchi nuqtaga qaytarib berish kerakligini aytdi. Uning aytganlari shu. Buning uchun har xil yo'llar bilan kamida 5 soat ishladim.

Bu mening kodim:

#include 

int rounding(int roundedNum);
int main()
{
   float userNum,
         rounded;

   printf("\nThis program will round a number to the nearest hundredths\n");
   printf("\nPlease enter the number you want rounded\n>");

   scanf("%f", &userNum);

   rounded = rounding (userNum);

   printf("%f rounded is %f\n", userNum, rounded);

   return 0;
}

int rounding(int roundedNum)
{


   return roundedNum;
}
2
floatNum kodini o'zgartirish uchun boshlang. float .
qo'shib qo'ydi muallif chux, manba
O'qituvchingiz bu ni o'qishi kerak. U sinfning A navbati bilan gaplashmoqda.
qo'shib qo'ydi muallif EJP, manba
Sizga to'g'ri javob bermasdan javob berish juda qiyin, men sizga beradigan eng yaxshi maslahatim shu: Agar 1.51 ni tanlasangiz va 1.5 (o'ninchi) bo'lsa, siz 10 ga o'girib boshlashingiz mumkin. 15 uchun int ga chiqarib, keyin 1.5 uchun 10.0 ga bo'linadi. Bu yordamga umid qilaman.
qo'shib qo'ydi muallif Elliott Frisch, manba
"So'ngra [ni] qaytib suzuvchi nuqtaga qaytsin": bu mantiqiy emas, chunki har bir suzuvchi nuqta raqami, albatta, emas .01 ahamiyatga ega emas, aniq aynan ikkilangan bir shkala bilan ifodalanishi mumkin.
qo'shib qo'ydi muallif user707650, manba
int ga translatsiya qilinmaydi, u kesiladi. Yuvarlamanın odatiy ta'rifi kesilmeyi o'z ichiga olmaydi. 0.5 (100 marta ko'paytirilgandan keyin) qo'shishingiz (yoki salbiy sonlar uchun) olib tashlashingiz bilan, bu savolga biroz engib o'tishingiz mumkin, garchi hatto sizda yaxlitlash qiymatlarining bir nechta varianti .
qo'shib qo'ydi muallif user707650, manba
X ga bir nechta soniya bilan urinib ko'rishga harakat qiling, intga o'tkazing va so'ngra X ning suzuvchi nuqtali versiyasiga bo'ling.
qo'shib qo'ydi muallif Asleepace, manba
Shunday qilib, uni "int yuvarlama (yumaloq yuvarlatılmışNum)" deb o'zgartiring?
qo'shib qo'ydi muallif JacobSedlik19, manba

5 javoblar

Sizning o'qituvchingiz:

float RoundHundredth(float x)
{
   //Scale the hundredths place to the integer place.
    float y = x * 100;

   //Add .5 to cause rounding when converting to an integer.
    y += .5f;

   //Convert to an integer, which truncates.
    int n = y;

   //Convert back to float, undo scaling, and return.

    return n/100.f;
}

Bu nuqsonli echim, chunki:

  • Ko'p S ilovalari ikkitomonlama suzuvchi nuqtadan foydalanadi. Ikki tomonlama suzuvchi nuqtada ikkita (½, ¼, ⅛, 1/16, 1/32, 1/64, ...) salbiy quvvatining ko'paytmasi bo'lmagan biron bir bo'lakni saqlash mumkin emas. Shunday qilib, 1/100 to'liq vakili bo'lolmaydi. Shuning uchun siz qanday hisob-kitob qilishingizdan qat'i nazar, aniq ravishda .01 yoki .79 ga qaytish mumkin emas. Eng yaxshi natijaga erishishingiz mumkin.

  • Agar suzuvchi nuqta raqamlari bo'yicha arifmetikni bajarganingizda, natijalar eng yaqin qiymatiga yuvarlanadi. Buning ma'nosi, x * 100 da, natijada umuman 100 marta emas, balki x . Yuvarlamadan uchun kichik xatolik yuz berdi. Bu xato, qiymatni yuvarlamanın bir tomondan boshqasiga o'zgarib, nuqtaga o'tishiga sabab bo'ladi, shuning uchun javobni noto'g'ri qilishingiz mumkin. Bunday xatolikka yo'l qo'ymaslik uchun usullar mavjud, biroq ular kirish darslari uchun juda murakkab.

  • To'xtab turish uchun aniq raqamga aylantirishga hojat yo'q; float uchun juft va truncf uchun trunc o'rnatilgan suzuvchi nuqta uchun kesish funksiyasi mavjud./p>

  • Bundan tashqari, butun sonni aylantirishdagi kesishning ishlatilishi bizni yaxlitlash uchun ½ ni qo'shishga majbur qildi. Ammo, biz tamsayı qiymatiga ega bo'lgan qiymatdan to'liq qiymatga aylantirmasdan foydalansak, float-qiymatlari yaxlitlash uchun ichki funktsiyadan foydalanishimiz mumkin: round float uchun ikki marta </​​code> va roundf .

Sizning S ilovangizda yaxshi formatlangan kirish/chiqish tartiblari mavjud bo'lsa, eng yaqin yuzga yoyilgan suzuvchi nuqta raqamini topishning oson yo'li uni (masalan, snprintf bilan) identifikatori % .2f . Tegishli S ilovasi raqamni o'nli kasrga aylantirib, o'nli punktdan keyin ikki raqamga aylantirib, yuqorida sanab o'tilgan arifmetik yaxlitlash xatolaridan saqlanish uchun to'g'ri yuvarlamadan foydalanadi. Biroq, siz string shaklida raqamga ega bo'lasiz.

2
qo'shib qo'ydi
Bu deyarli aniq istaganidek. Men dasturni taqdim qildim va faqatgina funktsiya deklaratsiyasi va asosiy vazifalar orasidagi bo'sh joyning yuqorisidagi fikrni unutib qo'yganim uchun belgilandi. Fikringiz uchun rahmat. Bu menga kerak bo'lgan narsani tushunishga yordam berdi.
qo'shib qo'ydi muallif JacobSedlik19, manba

Xo'sh, bu haqda o'ylab ko'raylik. Bunda bilishimiz kerak bo'lgan narsalardan biri shundaki, biz quydagi faylni butun songa aylantirishimiz mumkin:

float x = 5.4;
int y = (int) x;
//y is now equal to 5

Taqsimlaganda, suzuvchi chiziq kesiladi, ya'ni qiymatdan qat'i nazar (ya'ni, har doim 0 tomonga buriladi) o'nli kasrdan so'ng tushadigan narsalar.

Agar siz bu haqda va yuzinchi o'rin uchun qayg'urayotganingiz haqida o'ylayotgan bo'lsangiz, ehtimol siz o'zingizning suzuvchi nuqta raqamingizni manipulyatsiya qilishni o'z ichiga olgan bir tasavvurni tasavvur qilasiz, shunda siz uni int ga tashlaganingizda faqat siz ma'lumotni g'amxo'rlik (ya'ni, yuzinchi o'rinda bo'lgan raqamlar). Ko'paytirish bu erda foydali bo'lishi mumkin.

1
qo'shib qo'ydi

Yigiruvning eng keng tarqalgan ikki usuli "Noldan uzoqda" va "Bankirning yumaloqligi" (hatto "Yagona").

Pseudo-code for Rounding Away From Zero

EDIT Even though this is pseudo-code, I should have included the accounting for precision, since we are dealing with floating-point values here.

// this code is fixed for 2 decimal places (n = 2) and
// an expected precision limit of 0.001 (m = 3)
// for any values of n and m, the first multiplicand is 10^(n+1)
// the first divisor is 10^(m + 1), and
// the final divisor is 10^(n)

double roundAwayFromZero(double value) {
  boolean check to see if value is a negative number
  add precision bumper of (1.0/10000) to "value"//10000.0 is 10^4
  multiply "value" by 1000.0 and cast to (int) //1000.0 is 10^3
  if boolean check is true, negate the integer to positive
  add 5 to integer result, and divide by 10
  if boolean check is true, negate the integer again
  divide the integer by 100.0 and return as double //100.0 is 10^2

  ex: -123.456
      true
      -123.456 + (1.0/10000.0) => -123.4561
      -123.4561 * 1000.0 => -123456.1 => -123456 as integer
      true, so => -(-123456) => 123456
      (123456 + 5)/10 => 123461/10 => 12346
      true, so => -(12346) => -12346
      -12346/100.0 => -123.46 ===> return value
}

Sizning dastlabki savolingizda kodda aniq javob emas, balki faqat yo'nalish istagini bildirgansiz. Bu mantiqqa o'xshaydi, chunki men buni amalga oshirishga muvaffaq bo'laman. "Bankerning yumshoqlik" versiyasini siz mashq qilib bajarishingiz uchun qoldiraman.

0
qo'shib qo'ydi

Quyida ba'zi maslahatlar mavjud:

  1. Kerakli aniq raqamlar chapga siljishini ta'minlash uchun "10 kuchga ega" bilan floatlarni ko'paytirish.

  2. Yangi qiymatni yangi int o'zgaruvchiga o'tkazing, shuning uchun kiruvchi shkaf bitlari o'chiriladi

  3. Int ni 10 ga teng bir xil kuch bilan ajratib qo'ying, lekin shrift turini (masalan, 10.0) foydalaning, shuning uchun butun sonning aylanishiga aylantiriladi va yangi qiymat to'g'ri qiymatdir

  4. Sinash uchun , nozik (.2f) bilan printf foydalaning.

0
qo'shib qo'ydi
1 va 2 o'rtasida yaxlitlashni boshlash uchun tayyorgarlik kodi bo'lishi kerak. 2-qadam, yumaloq emas, fraksiyani samarali tarzda qisqartiradi.
qo'shib qo'ydi muallif chux, manba
Butunlay buzib tashlangan bu yerda .
qo'shib qo'ydi muallif EJP, manba
Siz kesish va tayyorgarlik kodiga bo'lgan ehtiyoj haqida to'g'ri fikrdasiz. Men buni talaba deb yozib qo'ydim. Talabgorga to'liq mantiqni berishni xohlamadi.
qo'shib qo'ydi muallif Srikanth N, manba

OK, shuning uchun o'ylayman! javoblaringiz uchun yall rahmat.

//function
float rounding(float roundedNumber)
{
   roundedNumber = roundedNumber * 100.0f + 0.5f;
   roundedNumber = (int) roundedNumber * 0.01f;

   return roundedNumber;
}

Agar 56,12567 raqamiga yuvarlantirilgan raqam sifatida kiritilgan bo'lsam, unda u 100 ga ko'paytirilib, 5612.567 ni tashkil qiladi. U yerdan 5 ga qo'shiladi. Bunday holda u shunday qiladi. Bu raqam 5613.067ga o'zgaradi. Keyinchalik uni int ga aylantirib kesib, keyin o'nli kasrni olish uchun ko'paytirasiz. U yerdan asosiy qiymatni qaytaradi va dumaloq raqamni chiqaradi. Yurishning juda g'alati usuli, lekin men buni yoyish funktsiyasidan foydalanmasdan qanday qilib amalga oshirayotganingizni tasavvur qilaman.

0
qo'shib qo'ydi
salbiy sonlar
qo'shib qo'ydi muallif technosaurus, manba