gpt4 book ai didi

c - 在用作 SQLite 聚合器的 C 函数中初始化结构中的值

转载 作者:太空宇宙 更新时间:2023-11-04 04:07:21 25 4
gpt4 key购买 nike

我有一个计算加权产品的程序(我改编 self 发现的另一个程序)。但是我不知道如何将 product_state 结构的 total_data 部分初始化为 1,这样我就不会总是以零的乘积结束。现在它保留默认的零值,以便我从 SQLite 传入的所有值都被清零。

我在大学里学过一些 C++,但从未深入研究过结构,回到这不是我的驾驶室。谢谢!

/* product.c */

#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1;

#include <stdlib.h>

typedef struct product_state_s {
double total_data; /* sum of (data * weight) values */
double total_wt; /* sum of weight values */
} product_state;

static void product_step( sqlite3_context *ctx, int num_values, sqlite3_value **values )
{
double row_wt = 1.0;
int type;
product_state *st = (product_state*)sqlite3_aggregate_context( ctx,
sizeof( product_state ) );
if ( st == NULL ) {
sqlite3_result_error_nomem( ctx );
return;
}

/* Extract weight, if we have a weight and it looks like a number */
if ( num_values == 2 ) {
type = sqlite3_value_numeric_type( values[1] );
if ( ( type == SQLITE_FLOAT )||( type == SQLITE_INTEGER ) ) {
row_wt = sqlite3_value_double( values[1] );
}
}

/* Extract data, if we were given something that looks like a number. */
type = sqlite3_value_numeric_type( values[0] );
if ( ( type == SQLITE_FLOAT )||( type == SQLITE_INTEGER ) ) {
st->total_data *= row_wt * sqlite3_value_double( values[0] );
st->total_wt += row_wt;
}
}

static void product_final( sqlite3_context *ctx )
{
double result = 0.0;
product_state *st = (product_state*)sqlite3_aggregate_context( ctx,
sizeof( product_state ) );
if ( st == NULL ) {
sqlite3_result_error_nomem( ctx );
return;
}

if ( st->total_wt != 0.0 ) {
result = st->total_data / st->total_wt;
}
sqlite3_result_double( ctx, result );
}

int product_init( sqlite3 *db, char **error, const sqlite3_api_routines *api )
{
SQLITE_EXTENSION_INIT2(api);

sqlite3_create_function( db, "product", 1, SQLITE_UTF8,
NULL, NULL, product_step, product_final );
sqlite3_create_function( db, "product", 2, SQLITE_UTF8,
NULL, NULL, product_step, product_final );

return SQLITE_OK;
}

最佳答案

product_step 中,在对 st == NULL 进行测试后,尝试添加以下内容:

if (0.0 == st->total_data) st->total_data = 1.0;

一般来说,您应该非常小心地比较浮点值是否相等。 float 学的精度有限。然而,如果行中的值都不为零,直接比较在这里应该可以正常工作:第一次通过时,sqlite3_aggregate_context 返回的缓冲区已被 sqlite 清零,因此该值应该比较相等到 0.0

如果行值可能为零(而且很可能是),您应该向结构添加状态以判断初始化是否已完成:

typedef struct product_state_s {
double total_data; /* sum of (data * weight) values */
double total_wt; /* sum of weight values */
bool did_init;
} product_state;

之后,不是测试 st->total_data 是否为零,而是:

if (!did_init) {
st->total_data = 1.0;
st->did_init = true;
}

关于c - 在用作 SQLite 聚合器的 C 函数中初始化结构中的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4171099/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com