Как написать функцию constexpr
, чтобы обменивать константу целого числа, не полагаясь на расширения компилятора, и можете ли вы привести пример о том, как это сделать?Как написать функцию constexpr swap для изменения endianess целого числа?
ответ
Да, это довольно легко; здесь рекурсивный (C++ 11-совместимый) реализация (только неподписанные интегральные типы):
#include <climits>
#include <cstdint>
#include <type_traits>
template<class T>
constexpr typename std::enable_if<std::is_unsigned<T>::value, T>::type
bswap(T i, T j = 0u, std::size_t n = 0u) {
return n == sizeof(T) ? j :
bswap<T>(i >> CHAR_BIT, (j << CHAR_BIT) | (i & (T)(unsigned char)(-1)), n + 1);
}
Здесь я использую j
в качестве аккумулятора и n
в качестве счетчика цикла (индексирование байт) ,
Если у вас есть компилятор, поддерживающий C++17 fold expressions, что можно написать что-то, что расширяющийся вне в точности то, что вы хотите написать вручную:
template<class T, std::size_t... N>
constexpr T bswap_impl(T i, std::index_sequence<N...>) {
return ((((i >> (N * CHAR_BIT)) & (T)(unsigned char)(-1)) <<
((sizeof(T) - 1 - N) * CHAR_BIT)) | ...);
}; // ^~~~~ fold expression
template<class T, class U = typename std::make_unsigned<T>::type>
constexpr U bswap(T i) {
return bswap_impl<U>(i, std::make_index_sequence<sizeof(T)>{});
}
Преимущество этой формы в том, что, поскольку он не использует циклы или рекурсии, вы в значительной степени гарантированно получаете оптимальную сборку - на x86-64, clang даже управляет work out to use the bswap
instruction.
Вдохновленный ecatmur Я предлагаю следующее решение, которое имеет потенциально лучшую производительность, когда компилятор не обнаруживает bswap (O (log (n)) vs O (N)). Учитывая, что N обычно < = 8 это, вероятно, не имеет значения, до сих пор:
template <typename T>
typename std::enable_if<std::is_unsigned<T>::value,T>::type
constexpr alternating_bitmask(const size_t step){
T mask(0);
for (size_t i=0;i<digits<T>();i+=2*step){
mask|=(~T(0)>>(digits<T>()-step))<<i;
}
return mask;
}
template <typename T>
typename std::enable_if<std::is_unsigned<T>::value,T>::type
constexpr bswap(T n){
for (size_t i=digits<unsigned char>();i<digits<T>();i*=2){
n = ((n&(~(alternating_bitmask<T>(i))))>>i)|
((n&((alternating_bitmask<T>(i))))<<i);
}
return n;
}
Поскольку эта форма является более сложным, чем решение ecatmur в компилятор имеет более жесткую оптимизацию рабочих мест, но лязг до сих пор считает, что мы имеем в виду BSWAP.
Это решение на самом деле имеет временную сложность Θ (N), так как внутренний цикл (не считая оптимизаций) имеет амортизированную сложность Θ (N/log N) (за итерацию внешнего цикла). Чтобы получить фактический Θ (log N), битмаски должны быть сохранены в памяти, например. предварительно вычисляется в массив. –
@ArneVogel это правда, я просто предположил, что битмаски будут компилировать константы времени, поскольку функция, которая их генерирует, является constexpr. – Lykos
- 1. Функция Scala для изменения целого числа
- 2. Как написать функцию для определения подсчета числа 16-разрядного целого числа с использованием php или javascript?
- 3. Вставка матрицы и целого числа в функцию
- 4. Как написать функцию для изменения на мыши?
- 5. Inverse Modulo для целого числа
- 6. Тестирование endianess во время компиляции: эта функция constexpr соответствует стандарту?
- 7. Python - Parse float string для целого числа
- 8. как написать функцию для чисел
- 9. Функция для вычисления целого числа как десятичного числа
- 10. Назначение значения/числа/целого числа для изображения
- 11. Как написать «слово» представление целого числа в файл в Java?
- 12. Найти многочлен для целого числа
- 13. нахождение целого числа части числа
- 14. Нет приглашения для целого числа
- 15. Создание целого числа для Float
- 16. Python regex для целого числа?
- 17. Неверный код для целого числа
- 18. факторизации целого числа
- 19. Как я могу специализировать шаблон C++ для целого целого числа?
- 20. Можно ли написать числовую функцию swap() в JavaScript?
- 21. Сканирование действительного целого числа
- 22. Недопустимый синтаксис для целого числа
- 23. Взаимозаменяемость строки для целого числа
- 24. Проверка ввода для целого числа
- 25. rspec raise_on_type_mismatch для целого числа
- 26. Regex для проверки целого числа
- 27. Ищете функцию constexpr ceil
- 28. Двоичные данные для числа с конверсией endianess в JavaScript
- 29. Как использовать happy.js для проверки целого числа?
- 30. Как отобразить определенную строку для целого числа?
Что такое «континент целого»? В чем смысл 15? –
@KerrekSB Что бы это ни было. Я не задавал этот вопрос. Мой вопрос заключается в том, как поменять big-endian на little-endian и наоборот. – user1095108
@KerrekSB: В контексте C++ (и большинства программ в целом), когда говорят целое число, они обычно ссылаются на целочисленный объект. То есть область памяти, используемая для хранения целочисленных данных, обычно является одним из основных целых типов (char, short, int, long и long long вместе с их неподписанными вариантами). Вы действительно никогда не сталкивались с этим использованием? –