Посмотрите этот фрагмент кода
int main()
{
unsigned int a = 1000;
int b = -1;
if (a>b) printf("A is BIG! %d\n", a-b);
else printf("a is SMALL! %d\n", a-b);
return 0;
}
Это дает вывод: МАЛЕНЬКОГО: 1001
Я не понимаю то, что происходит здесь. Как делает> работа оператора здесь? Почему меньшее, чем "b"? Если это действительно меньше, почему я получаю положительное число (1001) как различие?
У вас довольно мощные возможности композиции с Option:
def getURL : Option[URL]
def getDefaultURL : Option[URL]
val (host,port) = (getURL orElse getDefaultURL).map( url => (url.getHost,url.getPort) ).getOrElse( throw new IllegalStateException("No URL defined") )
-121--809616- Q1: Она работает отсюда, и, вероятно, из многих других мест. Однако обратите внимание, что геолокация с IP-адресов не очень надежная наука. Вы получите местоположение вашего интернет-провайдера, которое может быть довольно далеко, и, кроме того, базы данных IP-местоположения не всегда соответствуют последним изменениям, поэтому у вас может не быть данных для конкретного IP-адреса, что, вероятно, происходит в вашем случае.
MaxMind, который предлагает популярную базу данных IP-адрес, опубликованную статистику по своей базе данных:
Q2: Единственный способ получить геолокацию с IP-адреса через API-интерфейс Google Maps v3 - это использовать тот же метод, что и в примере, который вы предоставили . Однако если вы обнаружите, что любая другая база данных геолокации, например MaxMind GeoLite City , является более точной для вашей страны, вы можете сделать геолокацию с IP-адресов самостоятельно, а не делегировать ее в Google Maps.
-121--4950790- Двоичные операции между различными интегральными типами выполняются в пределах «общего» типа, определяемого так называемыми обычными арифметическими преобразованиями (см. языковую спецификацию, 6.3.1.8). В данном случае тип «common» - без знака int
. Это означает, что int
операнд (ваш b
) будет преобразован в неподписанный int
перед сравнением, а также с целью вычитания.
При преобразовании -1
в неподписанную int
получается максимально возможное значение неподписанной int
(такое же, как UINT _ MAX
). Нет необходимости говорить, что оно будет больше, чем ваше неподписанное значение 1000
, что означает, что a > b
действительно неверно и a
действительно мало по сравнению с (неподписанный) b
. Ветвь if
в коде должна быть преобразована в ветвь else
, что и было замечено в эксперименте.
К вычитанию применяются те же правила преобразования. Ваш a-b
действительно интерпретируется как a - (неподписанный) b
, и результат имеет тип неподписанный int
. Такое значение не может быть напечатано со спецификатором формата % d
, так как % d
работает только со значениями со знаком . Ваша попытка напечатать его с помощью % d
приводит к неопределенному поведению, поэтому значение, которое вы видите напечатанным (даже если оно имеет логическое детерминированное объяснение на практике), совершенно бессмысленно с точки зрения языка Си.
Изменить: На самом деле, я могу ошибаться в отношении неопределенной части поведения.общая часть диапазона соответствующего целочисленного типа со знаком и без знака должна иметь идентичное представление (подразумевающее, согласно сноске 31, «взаимозаменяемость в качестве аргументов функций»). Таким образом, результатом выражения a - b
является беззнаковое 1001
, как описано выше, и если я что-то не упускаю, законно печатать это конкретное неподписанное значение со спецификатором % d
, так как оно попадает в положительный диапазон int
. Печать (без подписи) INT_MAX + 1
с помощью % d
не определена, но 1001u
в порядке.
Вы делаете без знаки без знака, то есть сравнение от 1000 до 2 ^ 32 - 1.
Выход подписан из-за% d в printf.
N.B. Иногда поведение при смешивании подписанных и без знакаемых операндов является компилятором. Я думаю, что лучше их избегать и делать казни, когда сомневаетесь.
В типичной реализации, где int
является 32-битным, -1 при преобразовании в unsigned int
составляет 4,294,967,295, что действительно ≥ 1000.
Даже если рассматривать вычитание в беззнаковом
мире, 1000 - (4,294,967,295) = -4,294,966,295 = 1,001
, что и получается.
Вот почему gcc
выдаст предупреждение при сравнении unsigned
и signed
. (Если предупреждение не появляется, установите флаг -Wsign-compare
)