Revision bea70575

View differences:

doc/avutil.txt
19 19
lls.c
20 20
mathematics.c           greatest common divisor, integer sqrt, integer log2, ...
21 21
mem.c                   memory allocation routines with guaranteed alignment
22
softfloat.c
23 22

  
24 23
Headers:
25 24
bswap.h                 big/little/native-endian conversion code
libavutil/Makefile
75 75
OBJS-$(ARCH_PPC) += ppc/cpu.o
76 76
OBJS-$(ARCH_X86) += x86/cpu.o
77 77

  
78
TESTPROGS = adler32 aes base64 cpu crc des lls md5 pca sha softfloat tree
78
TESTPROGS = adler32 aes base64 cpu crc des lls md5 pca sha tree
79 79
TESTPROGS-$(HAVE_LZO1X_999_COMPRESS) += lzo
80 80

  
81 81
DIRS = arm bfin sh4 x86
libavutil/softfloat.c
1
/*
2
 * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
3
 *
4
 * This file is part of Libav.
5
 *
6
 * Libav is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2.1 of the License, or (at your option) any later version.
10
 *
11
 * Libav is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with Libav; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
 */
20

  
21
#include <inttypes.h>
22
#include <stdio.h>
23
#include <assert.h>
24
#include "softfloat.h"
25
#include "common.h"
26
#include "log.h"
27

  
28
#undef printf
29

  
30
int main(void){
31
    SoftFloat one= av_int2sf(1, 0);
32
    SoftFloat sf1, sf2;
33
    double d1, d2;
34
    int i, j;
35
    av_log_set_level(AV_LOG_DEBUG);
36

  
37
    d1= 1;
38
    for(i= 0; i<10; i++){
39
        d1= 1/(d1+1);
40
    }
41
    printf("test1 double=%d\n", (int)(d1 * (1<<24)));
42

  
43
    sf1= one;
44
    for(i= 0; i<10; i++){
45
        sf1= av_div_sf(one, av_normalize_sf(av_add_sf(one, sf1)));
46
    }
47
    printf("test1 sf    =%d\n", av_sf2int(sf1, 24));
48

  
49

  
50
    for(i= 0; i<100; i++){
51
        START_TIMER
52
        d1= i;
53
        d2= i/100.0;
54
        for(j= 0; j<1000; j++){
55
            d1= (d1+1)*d2;
56
        }
57
        STOP_TIMER("float add mul")
58
    }
59
    printf("test2 double=%d\n", (int)(d1 * (1<<24)));
60

  
61
    for(i= 0; i<100; i++){
62
        START_TIMER
63
        sf1= av_int2sf(i, 0);
64
        sf2= av_div_sf(av_int2sf(i, 2), av_int2sf(200, 3));
65
        for(j= 0; j<1000; j++){
66
            sf1= av_mul_sf(av_add_sf(sf1, one),sf2);
67
        }
68
        STOP_TIMER("softfloat add mul")
69
    }
70
    printf("test2 sf    =%d (%d %d)\n", av_sf2int(sf1, 24), sf1.exp, sf1.mant);
71
    return 0;
72
}
libavutil/softfloat.h
1
/*
2
 * Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
3
 *
4
 * This file is part of Libav.
5
 *
6
 * Libav is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2.1 of the License, or (at your option) any later version.
10
 *
11
 * Libav is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with Libav; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
 */
20

  
21
#ifndef AVUTIL_SOFTFLOAT_H
22
#define AVUTIL_SOFTFLOAT_H
23

  
24
#include <stdint.h>
25
#include "common.h"
26

  
27
#define MIN_EXP -126
28
#define MAX_EXP  126
29
#define ONE_BITS 29
30

  
31
typedef struct SoftFloat{
32
    int32_t  exp;
33
    int32_t mant;
34
}SoftFloat;
35

  
36
static av_const SoftFloat av_normalize_sf(SoftFloat a){
37
    if(a.mant){
38
#if 1
39
        while((a.mant + 0x20000000U)<0x40000000U){
40
            a.mant += a.mant;
41
            a.exp  -= 1;
42
        }
43
#else
44
        int s=ONE_BITS + 1 - av_log2(a.mant ^ (a.mant<<1));
45
        a.exp   -= s;
46
        a.mant <<= s;
47
#endif
48
        if(a.exp < MIN_EXP){
49
            a.exp = MIN_EXP;
50
            a.mant= 0;
51
        }
52
    }else{
53
        a.exp= MIN_EXP;
54
    }
55
    return a;
56
}
57

  
58
static inline av_const SoftFloat av_normalize1_sf(SoftFloat a){
59
#if 1
60
    if(a.mant + 0x40000000 < 0){
61
        a.exp++;
62
        a.mant>>=1;
63
    }
64
    return a;
65
#elif 1
66
    int t= a.mant + 0x40000000 < 0;
67
    return (SoftFloat){a.exp+t, a.mant>>t};
68
#else
69
    int t= (a.mant + 0x40000000U)>>31;
70
    return (SoftFloat){a.exp+t, a.mant>>t};
71
#endif
72
}
73

  
74
/**
75
 * @return Will not be more denormalized than a+b. So if either input is
76
 *         normalized, then the output will not be worse then the other input.
77
 *         If both are normalized, then the output will be normalized.
78
 */
79
static inline av_const SoftFloat av_mul_sf(SoftFloat a, SoftFloat b){
80
    a.exp += b.exp;
81
    a.mant = (a.mant * (int64_t)b.mant) >> ONE_BITS;
82
    return av_normalize1_sf(a);
83
}
84

  
85
/**
86
 * b has to be normalized and not zero.
87
 * @return Will not be more denormalized than a.
88
 */
89
static av_const SoftFloat av_div_sf(SoftFloat a, SoftFloat b){
90
    a.exp -= b.exp+1;
91
    a.mant = ((int64_t)a.mant<<(ONE_BITS+1)) / b.mant;
92
    return av_normalize1_sf(a);
93
}
94

  
95
static inline av_const int av_cmp_sf(SoftFloat a, SoftFloat b){
96
    int t= a.exp - b.exp;
97
    if(t<0) return (a.mant >> (-t)) -  b.mant      ;
98
    else    return  a.mant          - (b.mant >> t);
99
}
100

  
101
static inline av_const SoftFloat av_add_sf(SoftFloat a, SoftFloat b){
102
    int t= a.exp - b.exp;
103
    if(t<0) return av_normalize1_sf((SoftFloat){b.exp, b.mant + (a.mant >> (-t))});
104
    else    return av_normalize1_sf((SoftFloat){a.exp, a.mant + (b.mant >>   t )});
105
}
106

  
107
static inline av_const SoftFloat av_sub_sf(SoftFloat a, SoftFloat b){
108
    return av_add_sf(a, (SoftFloat){b.exp, -b.mant});
109
}
110

  
111
//FIXME sqrt, log, exp, pow, sin, cos
112

  
113
static inline av_const SoftFloat av_int2sf(int v, int frac_bits){
114
    return av_normalize_sf((SoftFloat){ONE_BITS-frac_bits, v});
115
}
116

  
117
/**
118
 * Rounding is to -inf.
119
 */
120
static inline av_const int av_sf2int(SoftFloat v, int frac_bits){
121
    v.exp += frac_bits - ONE_BITS;
122
    if(v.exp >= 0) return v.mant <<  v.exp ;
123
    else           return v.mant >>(-v.exp);
124
}
125

  
126
#endif /* AVUTIL_SOFTFLOAT_H */

Also available in: Unified diff