首页 > 解决方案 > 在针对 64 位变量的文字整数上使用 NOT (~) 运算符时是否需要类型转换

问题描述

如果不是自动类型转换的规则阻止它工作,以下工作是否有效?

uint64_t u64val=3293;
#define ALIGNsize 4
u64val=(u64val+ALIGNsize-1)&~(ALIGNsize-1);

或者这是必需的:

uint64_t u64val=3293;
#define ALIGNsize 4
u64val=(u64val+ALIGNsize-1)&~((uint64_t)ALIGNsize-1);

如果是后者,是否有任何技巧可以使事情自动化,因此使用 32 位不会浪费,但仍然可以在 64 位下工作,而无需记住或知道数据大小?

标签: c++ctype-conversion

解决方案


我做了一个测试,就使用 NOT (~) 对齐而言,我想我想出了一些通用的东西。适用于 C 和 C++(在 C++ 中测试)。这里是示例应用程序。这很好还是我错过了一些东西(在接受之前要确保):

// TestAlign.cpp : This file contains the 'main' function. Program execution begins and ends there.
//

#include <stdint.h>
#include <stdio.h>
#include <tchar.h>

// alignment to a base2 factor

inline uint64_t AlignUp2(uint64_t value, int align)
{
  return (value+align-1)&~((uint64_t) align-1);
}

inline uint32_t AlignUp2(uint32_t value, int align)
{
  return (value+align-1)&~((uint32_t) align-1);
}

#define ALIGNUP232(value, align) ((value+align-1)&~((uint32_t) align-1))
#define ALIGNUP264(value, align) ((value+align-1)&~((uint64_t)align-1))
#define ALIGNUP2(value, align) ((sizeof(value)==4) ? ALIGNUP232(value, align) : ALIGNUP264(value, align))
 
int _tmain(int argc, TCHAR *argv[])
{
  if (argc<3) {
    _tprintf(_T("Usage: testgenericitems value alignvalue\n"));
    return 1;
  }

  uint64_t val64=_tcstoull(argv[1], NULL, 0);
  uint32_t val32=_tcstoul(argv[1], NULL, 0);

  uint32_t align=_tcstoul(argv[2], NULL, 0);

  uint32_t val32test;
  val32test=val32;
  val32test=(val32test+align-1) & ~(align-1);

  uint64_t val64test;
  val64test=val64;
  val64test=(val64test+align-1) & ~(align-1);

  _tprintf(_T("32bit Old Style Align %u up to multiple of %i = %u\n"), val32, align, val32test);
  _tprintf(_T("64bit Old Style Align %llu up to multiple of %i = %llu\n"), val64, align, val64test);

  val32test=val32;
  val32test=AlignUp2(val32test, align);

  val64test=val64;
  val64test=AlignUp2(val64test, align);

  _tprintf(_T("32bit c++ Align %u up to multiple of %i = %u\n"), val32, align, val32test);
  _tprintf(_T("64bit c++ Align %llu up to multiple of %i = %llu\n"), val64, align, val64test);

  val32test=val32;
  val32test=ALIGNUP2(val32test, align);

  val64test=val64;
  val64test=ALIGNUP2(val64test, align);

  _tprintf(_T("32bit c Align %u up to multiple of %i = %u\n"), val32, align, val32test);
  _tprintf(_T("64bit c Align %llu up to multiple of %i = %llu\n"), val64, align, val64test);

  return 0;
}

推荐阅读