common: extract fp16 routines into their own file.

We might want to use them elsewhere.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell
2021-02-01 13:29:18 +10:30
parent 06a54606a3
commit cc4ea9420a
8 changed files with 82 additions and 54 deletions

View File

@@ -32,6 +32,7 @@ COMMON_SRC_NOGEN := \
common/ecdh_hsmd.c \
common/features.c \
common/fee_states.c \
common/fp16.c \
common/gossip_rcvd_filter.c \
common/gossip_store.c \
common/hash_u5.c \

50
common/fp16.c Normal file
View File

@@ -0,0 +1,50 @@
#include "config.h"
#include <assert.h>
#include <ccan/bitops/bitops.h>
#include <common/fp16.h>
fp16_t u64_to_fp16(u64 val, bool round_up)
{
u16 mantissa_bits, mantissa, exponent;
if (val == 0)
return 0;
/* How many bits do we need to represent mantissa? */
mantissa_bits = bitops_hs64(val) + 1;
/* We only have 11 bits, so if we need more, we will round. */
if (mantissa_bits > 11) {
exponent = mantissa_bits - 11;
mantissa = (val >> exponent);
/* If we're losing bits here, we're rounding down */
if (round_up && (val & ((1ULL << exponent)-1))) {
mantissa++;
if (mantissa == (1 << 11)) {
mantissa >>= 1;
exponent++;
}
}
/* huge number? Make it max. */
if (exponent >= 32) {
exponent = 31;
mantissa = (1 << 11)-1;
}
} else {
exponent = 0;
mantissa = val;
}
assert((mantissa >> 11) == 0);
return (exponent << 11) | mantissa;
}
bool amount_msat_less_fp16(struct amount_msat amt, fp16_t fp)
{
return amt.millisatoshis < fp16_to_u64(fp); /* Raw: fp16 compare */
}
bool amount_msat_greater_fp16(struct amount_msat amt, fp16_t fp)
{
return amt.millisatoshis > fp16_to_u64(fp); /* Raw: fp16 compare */
}

19
common/fp16.h Normal file
View File

@@ -0,0 +1,19 @@
/* 5 bit exponent, 11 bit mantissa approximations of min/max */
#ifndef LIGHTNING_COMMON_FP16_H
#define LIGHTNING_COMMON_FP16_H
#include "config.h"
#include <common/amount.h>
typedef u16 fp16_t;
static inline u64 fp16_to_u64(fp16_t val)
{
return ((u64)val & ((1 << 11)-1)) << (val >> 11);
}
fp16_t u64_to_fp16(u64 val, bool round_up);
bool amount_msat_less_fp16(struct amount_msat amt, fp16_t fp);
bool amount_msat_greater_fp16(struct amount_msat amt, fp16_t fp);
#endif /* LIGHTNING_COMMON_FP16_H */

View File

@@ -227,42 +227,6 @@ struct gossmap_chan *gossmap_find_chan(const struct gossmap *map,
return NULL;
}
static fp16_t u64_to_fp16(u64 val, bool round_up)
{
u16 mantissa_bits, mantissa, exponent;
if (val == 0)
return 0;
/* How many bits do we need to represent mantissa? */
mantissa_bits = bitops_hs64(val) + 1;
/* We only have 11 bits, so if we need more, we will round. */
if (mantissa_bits > 11) {
exponent = mantissa_bits - 11;
mantissa = (val >> exponent);
/* If we're losing bits here, we're rounding down */
if (round_up && (val & ((1ULL << exponent)-1))) {
mantissa++;
if (mantissa == (1 << 11)) {
mantissa >>= 1;
exponent++;
}
}
/* huge number? Make it max. */
if (exponent >= 32) {
exponent = 31;
mantissa = (1 << 11)-1;
}
} else {
exponent = 0;
mantissa = val;
}
assert((mantissa >> 11) == 0);
return (exponent << 11) | mantissa;
}
static u32 init_node_arr(struct gossmap_node *node_arr, size_t start)
{
size_t i;
@@ -822,12 +786,10 @@ bool gossmap_chan_capacity(const struct gossmap_chan *chan,
int direction,
struct amount_msat amount)
{
if (amount.millisatoshis /* Raw: fp16 compare */
< fp16_to_u64(chan->half[direction].htlc_min))
if (amount_msat_less_fp16(amount, chan->half[direction].htlc_min))
return false;
if (amount.millisatoshis /* Raw: fp16 compare */
> fp16_to_u64(chan->half[direction].htlc_max))
if (amount_msat_greater_fp16(amount, chan->half[direction].htlc_max))
return false;
return true;

View File

@@ -4,13 +4,11 @@
#include <bitcoin/short_channel_id.h>
#include <ccan/typesafe_cb/typesafe_cb.h>
#include <common/amount.h>
#include <common/fp16.h>
struct node_id;
struct pubkey32;
/* 5 bit exponent, 11 bit mantissa approximations of min/max */
typedef u16 fp16_t;
struct gossmap_node {
/* Offset in memory map for node_announce, or 0. */
u32 nann_off;
@@ -38,11 +36,6 @@ struct gossmap_chan {
} half[2];
};
static inline u64 fp16_to_u64(fp16_t val)
{
return ((u64)val & ((1 << 11)-1)) << (val >> 11);
}
struct gossmap *gossmap_load(const tal_t *ctx, const char *filename);
/* Call this before using to ensure it's up-to-date. Returns true if something

View File

@@ -1,5 +1,8 @@
#include "../fp16.c"
#include <common/pseudorand.h>
#include <common/type_to_string.h>
#include <stdio.h>
#include "../gossmap.c"
#include <wire/wire.h>
/* AUTOGENERATED MOCKS START */
/* Generated stub for amount_asset_is_main */