Як атрымаць правільнае значэнне/і% аператараў?

Я хачу зрабіць наступныя рэчы:

Я выкарыстоўваю зменную Int а , каб захаваць ўвод з кансолі, а затым я зрабіць наступнае:

int b = a/16;

Калі а гэта 64 ці 32, я атрымліваю 4 або 2. Але калі а 63, я чакаю атрымаць 4, але я атрымліваю 3. Ці існуюць якія-небудзь спосабы ў C каб атрымаць акругленае значэнне?

Edit. More details:

rang 1 to 16 should get 1,
rang 17 to 32 should get 2,
rang 33 to 48 should get 3,
rang 49 to 64 should get 4
3
па-ранейшаму павінны быць 4
дададзена аўтар user2131316, крыніца
любы лік, і я дадаў больш дэталяў у посьце
дададзена аўтар user2131316, крыніца
павінна быць адмоўны лік і 0
дададзена аўтар user2131316, крыніца
Што гэта такое, што вы хочаце? <�Код> круглы (а/16,0) , акругліць: (а + 15)/16 ?
дададзена аўтар Daniel Fischer, крыніца
Як вы хацелі б разглядаць адмоўныя лікі і 0?
дададзена аўтар Daniel Fischer, крыніца
Калі ўсё гарантавана будзе станоўчым, (дывідэнд - 1)/дзельнік + 1 гэта самы просты спосаб. (Вы можаце напісаць, што (дывідэнтных + (дзельнік - 1))/дзельнік , калі вы аддаеце перавагу.)
дададзена аўтар Daniel Fischer, крыніца
Вы не «выкажам здагадку», каб атрымаць 4. вы хочаце 4, па нейкай прычыне, але калі вы дзеліце 63 цацкі ад 16 дзяцей, кожны з якіх атрымлівае 3.
дададзена аўтар Elazar, крыніца
або круглай да бліжэйшага-сувязяў ўверх (а + 8)/16) (для станоўчага а )?
дададзена аўтар Pascal Cuoq, крыніца
@ User2131316 ... Праверце мой адказ.
дададзена аўтар Navnath Godse, крыніца
@ User2131316 ... /16 гэта выправіць, ці ён можа быць зменены на любы нумар -> а/5 , а/13 , .. .?
дададзена аўтар Navnath Godse, крыніца
@ User2131316 ... Што, калі вынік а = 61,60 ?
дададзена аўтар Navnath Godse, крыніца

7 адказы

Пры выкарыстанні аператара дзялення / з двума Int аргументы, ён будзе вяртае Int , які ўяўляе усечаны вынік.

Вы можаце атрымаць закругленымі ўверх дзяленне без выкарыстання лікаў з якая плавае кропкай, як гэта:

int a;
int den = 16;
int b = (a + den - 1)/den;

Што дасць вам тое, што вы чакаеце:

a ∈      [0], b =        0/16 = 0,
a ∈  [1, 16], b = [16, 31]/16 = 1,
a ∈ [17, 32], b = [32, 47]/16 = 2,
a ∈ [33, 48], b = [48, 63]/16 = 3,
a ∈ [49, 64], b = [64, 79]/16 = 4,
...

Звярніце ўвагу, што гэта толькі праца, калі а і б пазітывы, і сцеражыцеся магчымага перапаўнення а + дэн . Калі а + дэн падазраецца магчыма перапаўненне, то вы маглі б выкарыстоўваць іншы варыянт гэтага выказвання:

int b = (a - 1)/den + 1;

Адзіным недахопам з'яўляецца тое, што ён будзе вяртаць 1 пры а = 0 . Калі гэта праблема, вы можаце дадаць нешта накшталт:

int b = (a - 1)/den + 1 - !a;

Звярніце ўвагу, што вы можаце таксама апрацоўваць адмоўныя значэння а такім жа чынам (круглая ад нуля):

int b = (a > 0) ? (a - 1)/den + 1 : (a - den + 1)/den;
4
дададзена

Цэлалікавых дзяленне / ў C ня робіць <�моцны> rouding , замест гэтага, ён робіць <�моцны> ўсячэнне .

2
дададзена
так, але як атрымаць значэнне падобнага
дададзена аўтар user2131316, крыніца
@ User2131316 Глядзі адказы Лундин-х і praks411 за спосаб зрабіць гэта з дапамогай плавае кропкай дзялення і акруглення. Глядзіце мой адказ на спосаб зрабіць гэта з дапамогай простага падзелу на цэлы лік.
дададзена аўтар zakinster, крыніца

<�Моцны> Рашэнне

int ans, newNo;
int no = 63;//Given number
int dNo = 16;//Divider

newNo = (no % dNo) ? (dNo - (no % dNo) + no) : no;//Round off number

ans = newNo/dNo;

рэдагаваць

<�Моцны> Аптымізаваць рашэнне

<�Код> ANS = (няма/Дно) + !! (без% Дно);

1
дададзена
Вы можаце пазбегнуць галінавання, напісаўшы анс = няма/Дно + !! (без% Дна);
дададзена аўтар zakinster, крыніца
@zakinster ... дзякуй за прапанову.
дададзена аўтар Navnath Godse, крыніца

Самы просты спосаб атрымаць тое, што вы хочаце, каб выкарыстоўваць нумары з якая плавае кропкай.

#include 
#include 

int main(void) 
{
  double a = 63.0;
  double b = 16.0;

  printf("%d", (int) round(a/b));

  return 0;
}

Carefully pay attention when casting from float numbers to int, and vise versa. For example, round(63/16) is incorrect. It returns a double, but achieves nothing, since the literals 63 and 16 are integers. The division is done before the value is passed to the function. The correct way is to make sure that one or both operands are of type double: round(63.0/16.0)

0
дададзена
Змена вельмі простае цэлае рашэнне з якая плавае кропкай адной не вельмі добрая ідэя. Ён мае горшы прадукцыйнасць (аперацыі з якая плавае кропкай), гэта больш схільныя памылак (як вы сказалі ў адказе) і менш партатыўная (не заўсёды магчымыя ў кодзе ядра, або мікракантролеры).
дададзена аўтар Shahbaz, крыніца
Акрамя таго, толькі 80-біт двайны можа захоўваць 64-разраднае Int без страты дакладнасці.
дададзена аўтар zakinster, крыніца
Найпросты спосаб? Ці з'яўляецца (цэлае) круглы (а/(двайны) б) сапраўды прасцей, чым (а + Ь-1)/б ?
дададзена аўтар zakinster, крыніца

што вы спрабуеце гэта conceptualy ня правільна, але ўсё ж, калі вы хочаце такі ж вынік, як вы сказалі, у вашым пытанні, вы можаце паспрабаваць для стандартнай функцыі двайны (двайны столі х) , аб якой гаварылася ў math.h

Раўндаў х ўверх, вяртаючы найменшую цэлае значэнне, якое не менш, чым х.

0
дададзена

Вы можаце паспрабаваць выкарыстаць наступны

 int b = (int)ceil((double)a/16);
0
дададзена
Гэта нармальна для 32-разрадных цэлых лікаў, але можа пайсці не так для 64-разрадных ...
дададзена аўтар Oliver Charlesworth, крыніца

Паколькі C INT дзяленне заўсёды акругляецца ў бок нуля, просты трук, вы можаце выкарыстоўваць, каб зрабіць яго вакол раўнамерна, каб дадаць «0.5» у колькасці да ўзнікнення акругленне. Напрыклад, калі вы хочаце падзяліць на 32, выкарыстоўвайце

x = (a+16)/32;

ці ў больш агульным выпадку, для/б, дзе а і Ь абодва з'яўляюцца станоўчымі:

x = (a+b/2)/b;

На жаль, адмоўныя лікі ўскладняць гэта крыху, таму што, калі вынік адмоўны, то вам неабходна адняць 0,5, а не дадаваць яго. Гэта не праблема, калі вы ўжо ведаеце, што гэта будзе станоўчым або адмоўным, калі вы пішаце код, але калі мець справу з абодвума станоўчымі і адмоўнымі адказамі становіцца брудным. Вы можаце зрабіць гэта, як гэта ...

x = (a+((a/b>0)?1:-1)*(b/2))/b;

але на гэтым этапе ён пачынае станавіцца даволі складаным - гэта, напэўна, лепш проста кінуць плаваць і выкарыстоўваць раўнд функцыі.

-

[Рэдагаваць], як zakinster паказаў, хоць пытанне, зададзены для «круглых» значэнняў, прыклады, прыведзеныя на самай справе патрабуецца CEIL . Спосаб зрабіць гэта з Інтс будзе:

x = (a+b-1)/b;

Зноў жа, калі адказ можа быць адмоўным гэта становіцца складаней:

x = (a+((a/b>0)?1:-1)*(b-1))/b;

Я пакіну мой першапачатковы адказ на нават акругленне толькі ў выпадку, калі хто-то зацікаўлены.

0
дададзена
Ён не хоча, каб <�я> раўнд , ён хоча, каб <�я> CEIL , см УН.
дададзена аўтар zakinster, крыніца