1

Тема: Оператор % повертає від'ємні значення

Я так давно не використовував %, що зовсім забув як він працює.
І вот тепер довелося його використати.
Я думав, що він, як звичайний mod, даватиме значення з діапазону [0, d) (для v % d), а він вернув від'ємні числа.

Джерело : microsoft docs C# operator %

Питання :
Звідки ростуть ноги в цієї проблеми ?
Невже в компанії крихітномяких розробкою C# займалися люди які клали болт на таке неподобство ?

Намагався щось знайти по цій темі.. Дехто каже, що це із-за того, що процесори так реалізують цю операцію, відповідно і в асемблері вона так працює.. Але де C#, а де Assembler.. Короче в мене горить пердак від такої реалізації. Сподіваюсь, що тут є люди, яким буде не лінь пояснити, чого % працює саме так.

upd:
На всякий випадок, уточню: проблемане не в тому, що % вертає від'ємні значення, а в тому, що % вертає значення з діапазону (-d, d). А повинен би був вертати з [0, d).

2

Re: Оператор % повертає від'ємні значення

Мабуть тому що цей оператор повертає дійсно залишок а не модуль. Здається такаж поведінка була характерна для С++98/03 стандарта. Якщо я звичайно нічого не наплутав

Подякували: leofun011

3 Востаннє редагувалося ReAl (26.08.2018 20:30:00)

Re: Оператор % повертає від'ємні значення

У першу чергу це залежить від того, яку поведінку очікують від /, бо % то залишок від / («(a/b)*b + a%b shall equal a»).
Якщо -8 / 3 == -3, то % повинно повертати додатне число 1
Якщо -8 / 3 == -2, то % повинно повертати від'ємне число -2

В C -1/2 == 0, операції /% працюють по другому рядку — цілочисельне ділення повертає результат ближче до 0 («truncation toward zero»), знак залишка такий, як знак діленого).

А от -1 >> 1 для від'ємних значень знакових цілих -- implementation defined, бо таки «від асемблера». Так само було зі знаком результата % у стандарті С89, в C99 це унормували, в С++ не знаю, чи взагалі було «від асемблера».

Ну а в C#, швидше за все, не стали видумувати зайвого.

Подякували: leofun01, P.Y.2

4

Re: Оператор % повертає від'ємні значення

ReAl написав:

-8 / 3 == -2 ...

В C -1/2 == 0 ...

:o

:o

А це звідки вилізло ? Якого біса мовотворці витворяють ?
Моє життя вже ніколи не буде таким як раніше.

5

Re: Оператор % повертає від'ємні значення

Загальне правило: якщо ви не хочете мати проблем, не використовуйте % для від'ємних чисел. Своя логіка є в будь-якому варіанті, але це не обов'язково та логіка, якою ви хотіли скористатися.
-1/2==0 - для конформності: -(1/2)==0, так чому ж (-1)/2 має бути іншим?

Подякували: ReAl, leofun012

6 Востаннє редагувалося ReAl (27.08.2018 07:56:38)

Re: Оператор % повертає від'ємні значення

leofun01 написав:
ReAl написав:

-8 / 3 == -2 ...

В C -1/2 == 0 ...

А це звідки вилізло ?

Та хоча б звідси truncation (і, відповідно, truncated division тут).
А взагалі я не хотів би, щоби -1 / 100 = -1
Якось воно надто неінтуітивно.

Подякували: leofun011

7

Re: Оператор % повертає від'ємні значення

ReAl написав:
leofun01 написав:
ReAl написав:

-8 / 3 == -2 ...

В C -1/2 == 0 ...

А це звідки вилізло ?

Та хоча б звідси truncation (і, відповідно, truncated division тут).
А взагалі я не хотів би, щоби -1 / 100 = -1
Якось воно надто неінтуітивно.

Тоді вже -1/100 = -100, найближче менше ціле, що ділиться на 100.

8

Re: Оператор % повертає від'ємні значення

koala написав:

Загальне правило: якщо ви не хочете мати проблем, не використовуйте % для від'ємних чисел.

Короче ясно-понятно. Коли завершу проект, перейду на Python.
"Особливі випадки не є настільки особливими, щоб порушувати правила." (wikipedia). Золоті слова.

koala написав:

-1/2==0 - для конформності: -(1/2)==0, так чому ж (-1)/2 має бути іншим?

-(1/2)==0 бо

1 / 2 == 0

  0000 0001    // == 1
/ 0000 0010    // == 2
= 0000 0000.1  // == 0.5
= 0000 0000    // == 0 (заокруглили до меншого)

(-1)/2 має бути іншим, бо

(-1) / 2 == -1

  1111 1111    // == -1
/ 0000 0010    // == 2
= 1111 1111.1  // == -0.5
= 1111 1111    // == -1 (заокруглили до меншого)

до меншого
МЕНШОГО
незалежно від того чи є аргумент < 0.

ReAl написав:

А взагалі я не хотів би, щоби -1 / 100 = -1
Якось воно надто неінтуітивно.

А мені як раз норм.

koala написав:

Тоді вже -1/100 = -100, найближче менше ціле, що ділиться на 100.

Та ну, це вже якось за дуже. Моя логіка таке не підтримує.

9

Re: Оператор % повертає від'ємні значення

Упс, проглючив. Там же /, а не %.
Звісно, -1/100 має бути десь у {0,-1}.

Подякували: leofun011

10 Востаннє редагувалося ReAl (28.08.2018 19:59:34)

Re: Оператор % повертає від'ємні значення

leofun01 написав:
ReAl написав:

А взагалі я не хотів би, щоби -1 / 100 = -1
Якось воно надто неінтуітивно.

А мені як раз норм.

Є звичайна шкільна задачка про трьох рибалок, які ловили всю ніч рибу, а вранці кожен вставав, думав, що інші сплять, рахував рибу, воно націло на трьох не ділилося, то він викидав одну рибину назад у річку, брав свою частину і йшов (так всі троє).
Питання — скільки вони наловили за ніч.

То у рибалок-математиків (здається, це Поль Дірак в юності таке втнув) там мінус дві рибини.
-2 / 3 = -1, залишок 1
Перший забрав свою -1 рибину
-2 - (-1) = -1
і викинув одну у річку
-1 - 1 = -2
Другий прокинувся, подумав, що інші ще сплять, повторив операцію. Те ж з третім.

Подякували: Yola, leofun012