Nano Hash - криптовалюты, майнинг, программирование

Предупреждение C (компилятор clang) Целочисленный литерал слишком велик, чтобы быть представленным целым числом со знаком

У меня есть этот кусок кода

#include <stdio.h>

typedef signed long long v2signed_long 
      __attribute__ ((__vector_size__ (sizeof(signed long long) * 2)));

int main()
{
        v2signed_long v = {4611686018427387904LL, -9223372036854775808LL};

        printf("%lli, %lli\n", v[0], v[1]);
        return 0;
}

Что дает следующее предупреждение (связанные вопросы не помогли):

:7:45: warning: integer literal is too large to be represented in
       a signed integer type, interpreting as unsigned
  [-Wimplicitly-unsigned-literal]
    v2signed_long v = {4611686018427387904LL, -9223372036854775808LL};

Есть ли способ решить это предупреждение? Спасибо!

20.02.2020

  • Без реальной проверки значений я полагаю, что @Eljay верен. Удивительным (для меня) фоном является то, что -1 — это не целочисленный литерал, а константное выражение, состоящее из целочисленного литерала 1 и унарного минус-оператора, который, как и следовало ожидать, меняет знак. Итак, литерал положительного целого числа 9223372036854775808 (к которому позже применяется унарный минус) действительно слишком велик для пространства длинных длинных значений, и решение именно то, что сказал Элджей: используйте наибольшее положительное целое число, измените его знак и вычтите один. Все еще выражение времени компиляции, так что никакого вреда. 20.02.2020
  • Отвечает ли это на ваш вопрос? Почему большинство отрицательное значение int вызывает ошибку о неоднозначных перегрузках функций? 20.02.2020
  • C такой злой язык. Конечно -9223372036854775808LL — положительное число, поэтому - :) Или вы можете перенести это на компьютер с дополнением до 1, это тоже решит проблему :) 20.02.2020
  • Еще одно решение: (int64_t) -0x8000000000000000. Когда C становится злым, отвечайте тем же! 20.02.2020

Ответы:


1

Проблема в том, что -9223372036854775808LL на самом деле не целочисленный литерал. Это литерал 9223372036854775808LL с примененным к нему унарным оператором -. Значение 9223372036854775808 слишком велико, чтобы поместиться в signed long long, поэтому вы получаете предупреждение.

Вы можете исправить это, используя вместо этого выражение -9223372036854775807LL - 1LL. Значение 9223372036854775807 соответствует signed long long, как и -9223372036854775807LL, затем вычитание 1 дает вам нужное значение.

В качестве альтернативы вы можете использовать макрос LLONG_MIN.

20.02.2020
  • используйте макрос LLONG_MIN Я полагаю, что это ответ и, вероятно, должен быть первым. 20.02.2020

  • 2

    Компилятор считает эту конструкцию

    -9223372036854775808LL
    

    как целочисленный литерал 9223372036854775808LL, для которого применяется унарный оператор -. Но значение 9223372036854775808 слишком велико, чтобы хранить его в объекте типа signed long long. Поэтому компилятор выдает ошибку.

    Вместо этого используйте

    #include <limits>
    
    //...
    
    v2signed_long v = 
    {
        std::numeric_limits<long long>::max(), std::numeric_limits<long long>::min()
    };
    

    Вот демонстрационная программа

    #include <iostream>
    #include <limits>
    #include <vector>
    
    int main() 
    {
        std::vector<long long> v =
        {
            std::numeric_limits<long long>::max(), std::numeric_limits<long long>::min()
        };
    
        for ( const auto &item : v ) std::cout << item << '\n';
    
        return 0;
    }
    

    Его вывод

    9223372036854775807
    -9223372036854775808
    

    Поскольку вы удалили тег C++, код в C может выглядеть так:

    #include <stdio.h>
    #include <limits.h>
    
    int main(void) 
    {
        long long int a[] = { LLONG_MAX, LLONG_MIN };
    
        printf( "%lld\n%lld\n", a[0], a[1] );
    
        return 0;
    }
    

    Вывод программы такой же, как показано выше.

    В любом случае гораздо лучше использовать этот подход вместо магических чисел с уловкой, которая только запутает читателей кода.

    20.02.2020
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..