小编phu*_*clv的帖子

汇编:在两个存储器地址之间移动

我正在尝试学习汇编(所以忍受我),我在这一行得到了一个编译错误:

mov byte [t_last], [t_cur]
Run Code Online (Sandbox Code Playgroud)

错误是

error: invalid combination of opcode and operands
Run Code Online (Sandbox Code Playgroud)

我怀疑这个错误的原因只是因为一个mov指令不可能在两个内存地址之间移动,但是半小时的谷歌搜索并且我无法确认这一点 - 是这样的吗?

另外,假设我是对的,这意味着我需要使用寄存器作为复制内存的中间点:

mov cl, [t_cur]
mov [t_last], cl
Run Code Online (Sandbox Code Playgroud)

什么是推荐使用的寄存器(或者我应该使用堆栈)?

x86 assembly instructions mov

19
推荐指数
4
解决办法
3万
查看次数

单个C代码中的printf和wprintf

在代码中使用printfwprintf一起使用时遇到问题.如果首先打印常规字符串,则wprintf不起作用.如果我wprintf先使用则printf不起作用.

#include <stdio.h>
#include <wchar.h>
#include <stdlib.h>
#include <locale.h>

int main() 
{
    setlocale(LC_ALL,"");

    printf("No printing!\n");
    wprintf(L"Printing!\n");
    wprintf(L"Wide char\n");
    printf("ASCII\n");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出:

No printing!
ASCII
Run Code Online (Sandbox Code Playgroud)

#include <stdio.h>
#include <wchar.h>
#include <stdlib.h>
#include <locale.h>

int main() 
{
    setlocale(LC_ALL,"");

    wprintf(L"Printing!\n");
    printf("No printing!\n");
    wprintf(L"Wide char\n");
    printf("ASCII\n");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出:

Printing!
Wide char
Run Code Online (Sandbox Code Playgroud)

我在64位Linux 3.0上使用gcc(GCC)4.6.1 20110819和glibc 2.14.

c gcc internationalization

19
推荐指数
2
解决办法
6893
查看次数

不带+运算符添加两个数字(澄清)

我知道我们可以使用二进制加法器的逻辑Sum = a XOR bCarry = a AND b

我也有一个解决方案:

int add(int a, int b)
{
     if(b == 0)
         return sum;
     sum = a ^ b;
     carry = (a & b) << 1;
     return add(sum,carry);
}
Run Code Online (Sandbox Code Playgroud)

我在这里不明白的是为什么在每次递归期间进位位移位或乘以2?

bit-manipulation

18
推荐指数
1
解决办法
1万
查看次数

使用find -exec重定向stdout并且不创建新shell

我有一个只写数据的脚本stdout.我需要为多个文件运行它并为每个输入文件生成不同的输出文件,我想知道如何使用find -exec它.所以我基本上尝试了几种变体(我cat为了可测试性而替换了脚本):

find * -type f -exec cat "{}" > "{}.stdout" \;
Run Code Online (Sandbox Code Playgroud)

但由于所有数据都被写入一个字面命名的文件,因此无法使其正常工作{}.stdout.

最终,我可以使用它:

find * -type f -exec sh -c "cat {} > {}.stdout" \;
Run Code Online (Sandbox Code Playgroud)

但是,虽然这个最新的形式适用cat,我的脚本需要通过几个初始化脚本加载环境变量,因此我最终得到:

find * -type f -exec sh -c "initscript1; initscript2; ...;  myscript {} > {}.stdout" \;
Run Code Online (Sandbox Code Playgroud)

这似乎是浪费,因为我已经在我当前的shell中初始化了所有内容.

有没有更好的方法来做到这一点find?欢迎其他单行.

unix linux

18
推荐指数
2
解决办法
1万
查看次数

如何使用像scanf这样的函数使用int16_t或int32_t

我理解int16_tint32_t在C中的方式是它们在您的计算机上分别被命名为16位和32位数字.我相信当你需要保证数字为16或32位时你会使用这些,因为不同的系统并不总是代表int32位或short16位(这个假设是正确的吗?当我在网上看时,我找到了混合的答案.) .

我的问题是当我要求它们实际上是16位或32位或其他什么时,我将如何使用一个函数scanf来获取来自具有int16_t或者int32_t或任何其他类型定义数字类型的用户的输入?有某种特殊的字符串修饰符吗?通常情况下,如果我想int从一个用户那里得到一个没有关心它实际表示多大的用户,我会写这样的东西

scanf("%d", &int);
Run Code Online (Sandbox Code Playgroud)

这是有效的,如果我传入一个,int32_t但我认为它只是因为int我的系统是32位,它没有特别给我一个32位数,而只是给了我一个int.我如何获得保证为32位的数字?我查看了这个字符串修饰符和其他一些地方的页面,但没有提到这些类型定义的数字类型.

编辑:自从收到我的问题的答案后,我做了一些谷歌搜索并找到了这个.我将它包括在下面以供参考.

uppercase hexadecimal printf format for uintptr_t

#define SCNd16   "d"
decimal scanf format for int16_t

#define SCNd32   "ld"
decimal scanf format for int32_t

#define SCNd8   "hhd"
decimal scanf format for int8_t

#define SCNdFAST16   "d"
decimal scanf format for int_fast16_t

#define SCNdFAST32   "ld"
decimal scanf format …
Run Code Online (Sandbox Code Playgroud)

c user-input scanf

18
推荐指数
1
解决办法
2万
查看次数

使用 valgrind 运行时 std::cos 给出不同的结果

我发现了一个影响我工作中的多个单元测试的问题,这种问题仅在使用 valgrind 运行单元测试时才会发生,因为对于相同的输入,从 std::cos 和 std::sin 返回的值是不同的,具体取决于是否单元测试是独立运行的,而不是在 valgrind 下运行。

这个问题似乎只发生在某些特定的输入上,因为许多单元测试都通过了相同的代码。

这是一个最低限度可重现的示例(稍微恶化,以便我的编译器不会优化任何逻辑):

#include <complex>
#include <iomanip>
#include <iostream>

int main()
{
    std::complex<long double> input(0,0), output(0,0);

    input = std::complex<long double>(39.21460183660255L, -40);
    std::cout << "input: " << std::setprecision(20) << input << std::endl;

    output = std::cos(input);
    std::cout << "output: " << std::setprecision(20) << output << std::endl;

    if (std::abs(output) < 5.0)
    {
        std::cout << "TEST FAIL" << std::endl;
        return 1;
    }

    std::cout << "TEST PASS" << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

正常运行时输出:

input: (39.21460183660254728,-40)
output: (6505830161375283.1118,117512680740825220.91) …
Run Code Online (Sandbox Code Playgroud)

c++ floating-point precision valgrind std

18
推荐指数
0
解决办法
641
查看次数

"epsilon"真的能保证浮点计算中的任何东西吗?

为了简化问题,我想说我想a / (b - c)floats 上计算表达式.

为了确保结果是有意义的,我可以检查bc是相等的:

float EPS = std::numeric_limits<float>::epsilon();
if ((b - c) > EPS || (c - b) > EPS)
{
    return a / (b - c);
}
Run Code Online (Sandbox Code Playgroud)

但是我的测试表明,如果可能的话,不能保证有意义的结果,也不能不提供结果.

情况1:

a = 1.0f;
b = 0.00000003f;
c = 0.00000002f;
Run Code Online (Sandbox Code Playgroud)

结果:不满足if条件,但表达式将生成正确的结果100000008(与浮点数的精度相同).

案例2:

a = 1e33f;
b = 0.000003;
c = 0.000002;
Run Code Online (Sandbox Code Playgroud)

结果:满足if条件,但表达式不会产生有意义的结果+1.#INF00.

我发现检查结果更可靠,而不是参数:

const float INF = numeric_limits<float>::infinity();
float x = a / (b - c); …
Run Code Online (Sandbox Code Playgroud)

floating-point floating-accuracy epsilon

17
推荐指数
1
解决办法
9372
查看次数

将浮点值从big endian转换为little endian

是否有可能将floats从大端转换为小端?我有一个来自PowerPC平台的大端值,我通过TCP发送到Windows进程(小端).这个值是a float,但是当我memcpy将值转换为Win32 float类型然后调用_byteswap_ulong该值时,我总是得到0.0000?

我究竟做错了什么?

c++ endianness

17
推荐指数
4
解决办法
5万
查看次数

C问题:无符号整数和按位运算中的填充位(C89)

我有很多代码对无符号整数执行按位运算.我编写了我的代码,假设这些操作是在固定宽度的整数上,没有任何填充位.例如,32位无符号整数的数组,其中所有32位可用于每个整数.

我希望让我的代码更具可移植性,并且我专注于确保我符合C89(在这种情况下).我遇到的一个问题是填充整数.拿这个极端的例子,取自GMP手册:

然而,在Cray矢量系统上,可以注意到short和int总是以8个字节存储(并且sizeof指示),但仅使用32或46位.指甲功能可以通过传递例如8*sizeof(int)-INT_BIT来解决这个问题.

我也在其他地方读过这种类型的填充.我昨晚实际上在SO上读了一篇文章(请原谅我,我没有链接,我将引用类似记忆的内容),如果你有一个带有60个可用位的双,另外4个可以用于填充和那些填充位可以用于某些内部目的,因此它们不能被修改.


因此,假设我的代码是在一个平台上编译的,其中unsigned int类型的大小为4个字节,每个字节为8位,但最重要的2位是填充位.在这种情况下UINT_MAX会是0x3FFFFFFF(1073741823)吗?

#include <stdio.h>
#include <stdlib.h>

/* padding bits represented by underscores */
int main( int argc, char **argv )
{
    unsigned int a = 0x2AAAAAAA; /* __101010101010101010101010101010 */
    unsigned int b = 0x15555555; /* __010101010101010101010101010101 */
    unsigned int c = a ^ b; /* ?? __111111111111111111111111111111 */
    unsigned int d = c << 5; /* ??  __111111111111111111111111100000 */
    unsigned int e = d >> 5; /* ?? __000001111111111111111111111111 */

    printf( "a: …
Run Code Online (Sandbox Code Playgroud)

c bit-manipulation padding bitwise-operators

17
推荐指数
1
解决办法
5103
查看次数

memcpy()通常比strcpy()快吗?

memcpy()通常速度比strcpy()(上最真实的平台)?(我假设字符串的大小是已知的.)

如果我正确地记得i386汇编程序,则会有loop指令复制给定数量的字节或单词.所以它是最快的方式,而strcpy()i386汇编程序实现将'\0'在一个简单的循环中使用手动检查.

所以我觉得在x86上memcpy()要快于strcpy().

其他架构是什么?

c performance x86 memcpy strcpy

17
推荐指数
2
解决办法
1万
查看次数