AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / user-5352127

dscerutti's questions

Martin Hope
dscerutti
Asked: 2024-11-22 11:14:09 +0800 CST

Existe uma maneira eficiente de sobrecarregar operadores para structs quando os dados subjacentes são por partes?

  • 5

Tenho vários métodos para acumular quantidades em números de precisão fixa com base no seguinte tipo de dados:

int95_t {
  long long int x;
  int y;
};

Os números são contados para frente xaté que possam ficar fora dos limites e retornar, momento em que yacumulam +1 para estouro e -1 para subfluxo. (Eu também tenho métodos para adicionar números de ponto flutuante, o que pode causar vários estouros ou subfluxos de xe, portanto, acumular várias vezes em y).

Os métodos para adicionar ou subtrair neste tipo de dados são um tanto complexos.

int95_t sum(const int95_t a, const int95_t b) {
  int95_t result = { a.x + b.x, a.y + b.y };
  result.y += (1 - (2 * (b.x < 0LL))) * ((a.x ^ result.x) < 0 && (a.x ^ b.x) >= 0LL) * 2;
  return result;
}

int95_t subtract(const int95_t a, const int95_t b) {
  const int95_t neg_b = { -b.x, -b.y + (2 * (b.x == LLONG_MIN)) };
  return sum(a, neg_b);
}

Sobrecarreguei os operadores +, -, +=, e -=para esse tipo de dado, mas isso não ajuda a limpar meu código tanto assim e pelo seguinte motivo: em muitos contextos, armazenarei não uma matriz de int95_tvalores, mas duas matrizes separadas de valores long long inte int. (O motivo é que há muitas condições sob as quais o acumulador supernário ypode ser ignorado com segurança, e eu quero conservar a largura de banda da memória.) Assim, tenho muitas situações em que, para adicionar um int95_t a outro nessas circunstâncias, parece que ainda preciso fazer:

long long int primary[8];
int secondary[8];
int95_t add_this = { 81573835283, 3816 };

for (int i = 0; i < 8; i++) {
  int95_t tmp = { primary[i], secondary[i] };
  tmp += add_this;
  primary[i] = tmp.x;
  secondary[i] = tmp.y;
}

Existe alguma maneira melhor? Eu esperaria poder contar com qualquer compilador C++ para interpretar corretamente algo assim no caso acima, mas não tenho certeza:

for (int i = 0; i < 8; i++) {
  { primary[i], secondary[i] } += add_this;
}

Obrigado por qualquer ajuda que vocês possam oferecer.

c++
  • 1 respostas
  • 44 Views
Martin Hope
dscerutti
Asked: 2023-09-02 01:59:47 +0800 CST

Esta conversão bit a bit é segura?

  • 10

Tenho uma situação em que preciso agrupar 16 bits em um número de 64 bits e depois lê-los como um número inteiro assinado no intervalo [ -32768, 32768 ). O método que escolhi para isso é calcular o número como um int assinado de 16 bits, convertê-lo imediatamente em um int não assinado de 16 bits e, em seguida, fazer o upcast para um int não assinado de 64 bits antes de executar a mudança de bit adequada para obter os 16 bits críticos no lugar apropriado.

Aqui está o pseudocódigo para criar o arranjo compactado de bits:

Given int x, y such that x - y >= -32768 and y - x < 32768;
const int MASK_POS = 45;
const unsigned short int u_s = x - y;
unsigned long long int ull_s = u_s;
ull_s <<= MASK_POS;

Aqui está o pseudocódigo para extrair a diferença nos números originais:

Given unsigned long long int ull_s with 16 bits encoding a signed integer in the 46th through 61st bits;
const unsigned short int u_s = ((ulls >> MASK_POS) & 0xffff);
const short int s_s = u_s;
const int difference_x_and_y = s_s;

Esta me parece uma maneira razoável de empacotar um número inteiro assinado e extraí-lo. Desconfio do comportamento específico da plataforma ao realizar mudanças de bits em números inteiros negativos, mas acho que converter para a forma não assinada do mesmo número de bits antes de atualizar o número de bits gerais no número e, ao contrário, extrair o não assinado inteiro com comprimento de bit desejado antes de converter para um inteiro com sinal de tamanho igual, será seguro.

(Caso alguém esteja curioso, haverá MUITO coisa acontecendo nos outros 48 bits desse número inteiro não assinado de 64 bits em que o material acaba - dos três bits mais altos aos 31 mais baixos e aos 14 do meio, tudo foi analisado. Certamente posso escrever alguns testes de unidade para garantir que esse comportamento se mantenha em qualquer arquitetura, mas se alguém puder ver uma falha agora, é melhor saber com antecedência. Obrigado!)

c++
  • 1 respostas
  • 86 Views

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Reformatar números, inserindo separadores em posições fixas

    • 6 respostas
  • Marko Smith

    Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não?

    • 2 respostas
  • Marko Smith

    Problema com extensão desinstalada automaticamente do VScode (tema Material)

    • 2 respostas
  • Marko Smith

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Martin Hope
    Fantastic Mr Fox Somente o tipo copiável não é aceito na implementação std::vector do MSVC 2025-04-23 06:40:49 +0800 CST
  • Martin Hope
    Howard Hinnant Encontre o próximo dia da semana usando o cronógrafo 2025-04-21 08:30:25 +0800 CST
  • Martin Hope
    Fedor O inicializador de membro do construtor pode incluir a inicialização de outro membro? 2025-04-15 01:01:44 +0800 CST
  • Martin Hope
    Petr Filipský Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não? 2025-03-23 21:39:40 +0800 CST
  • Martin Hope
    Catskul O C++20 mudou para permitir a conversão de `type(&)[N]` de matriz de limites conhecidos para `type(&)[]` de matriz de limites desconhecidos? 2025-03-04 06:57:53 +0800 CST
  • Martin Hope
    Stefan Pochmann Como/por que {2,3,10} e {x,3,10} com x=2 são ordenados de forma diferente? 2025-01-13 23:24:07 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve