对于Lua快速计算log2感兴趣的读者,本文将会是一篇不错的选择,我们将详细介绍lualog函数,并为您提供关于AndroidFFmpeg:对atof,log2和log2f的未定义引用、c–使用元编程
对于Lua快速计算log2感兴趣的读者,本文将会是一篇不错的选择,我们将详细介绍lua log函数,并为您提供关于Android FFmpeg:对atof,log2和log2f的未定义引用、c – 使用元编程来计算log2但是`编译终止’、Log4j怎么改可以让日志文件按时期分开存放,如:serverLog2015-03-24.log, serverLog2015-03-25.log、lua学习笔记之一(C/C++程序员的Lua快速入门[初阶话题])的有用信息。
本文目录一览:- Lua快速计算log2(lua log函数)
- Android FFmpeg:对atof,log2和log2f的未定义引用
- c – 使用元编程来计算log2但是`编译终止’
- Log4j怎么改可以让日志文件按时期分开存放,如:serverLog2015-03-24.log, serverLog2015-03-25.log
- lua学习笔记之一(C/C++程序员的Lua快速入门[初阶话题])
Lua快速计算log2(lua log函数)
lua 的源码,惊喜越来越多。比如今天看到了一个快速计算 log2(x) 的方法。代码如下:
想法也很朴素,就是把整数转换成 2^n 的形式,然后求出 n 就可以了。比如 256 是 2^8,所以这里数组 log_2[256] = 8,那些转换不成 2^n 的数也就被近似计算了,比如 255,我们知道 256 = 2^8,而 128 = 2^7,所以 128 和 256 之间的数都被近似成 256 了,结果也都是 8。我们可以看到 log_2[128] 到 log_2[255] 都等于 8。
这里误差也就是 1。完全可以忽略了。如果这个数大于 256,那么就让他除以 256,同时结果加 8 就可以了。最后的误差仍然是 1。
其实你也完全可以把这个 log_2 的数组设计的更大一些,这样需要进入 while 循环的条件就要求所求的数更大。作者定在 256 估计是考虑到在实际计算过程中对于大于等于 256 的数求 log2 已经很少用到了。这个 log_2 的数组你还可以设计的更合理一些,比如把 log_2[128] 到 log_2[255] 之间的数不全部设成 8,而是把靠近 128 的地方的数设成 7,把靠近 255 的地方设成 8,不过这样就又陷入到更麻烦的考虑中,比如到底把哪里开始设成 8,哪里设成 7 等等。本来是为了快速计算的一个函数,最后又变麻烦,必然不好。
最后我在网上搜索快速计算 log2 的方法的时候又看到了 quake III 中的神奇代码。我不得不说,quake III 真是一个神奇的引擎,里面有大量值得学习的代码,等我阅读完 lua 的源码之后下一步就是阅读它了。先来看看它是怎么进行 log2 计算的:
看到这段代码我真心都快被吓尿了。首先我只知道 (x) & (-x) 的意思是取出 x 末尾的 0 和第一次出现的 1。其他我就一概不明了。最神奇的是这里面又出现一个 magic number 0x077CB531U。上次在 quake III 里看到的那个牛顿转换的初始值的那个 magic number 的时候我就尿了。这次不例外。还好在网上看到了 Matrix67 给出的解释,不过没有仔细看,等过段时间再看看。
Lua :lobject.c
quake III:trick 代码
Matrix67:神秘常量复出!用0x077CB531计算末尾0的个数
Android FFmpeg:对atof,log2和log2f的未定义引用
以下是我的链接器列表:
-lavformat -lavcodec -lswscale -lavutil -lavfilter -lswresample -lavdevice -lpostproc
我抱怨以下错误
libavformat/hls.c:783: error: undefined reference to ''atof'' libavcodec/ffv1enc.c:146: error: undefined reference to ''log2'' libavcodec/imc.c:428: error: undefined reference to ''log2f''
以下是我的FFmpeg相关内容包括:
#include <stdint.h> #include <cstdlib> #define __STDC_CONSTANT_MACROS extern "C" { #include "libavcodec/avcodec.h" #include "libavformat/avformat.h" #include "libavutil/mathematics.h" #include "libavcodec/version.h" #include "libavutil/rational.h" #include "libavutil/avstring.h" #include "libswscale/swscale.h" }
以下是我用于交叉编译FFmpeg for android的buildscript:
#!/bin/bash cd ffmpeg-3.3.4 NDK=/path/to/ndk/android-ndk-r15c SYSROOT=$NDK/platforms/android-21/arch-arm/ TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64 AR=$TOOLCHAIN/bin/arm-linux-androideabi-ar CPREFIX=$TOOLCHAIN/bin/arm-linux-androideabi-ar CC=$TOOLCHAIN/bin/arm-linux-androideabi-gcc CXX=$TOOLCHAIN/bin/arm-linux-androideabi-g++ LD=$TOOLCHAIN/bin/arm-linux-androideabi-ld RANLIB=$TOOLCHAIN/bin/arm-linux-androideabi-ranlib STRIP=$TOOLCHAIN/bin/arm-linux-androideabi-strip function build_ffmpeg_android { ./configure \ --prefix=$PREFIX \ --disable-stripping \ --arch=arm \ --cpu=cortex-a8 \ --target-os=linux \ --enable-cross-compile \ --enable-debug \ --enable-pic \ --disable-programs \ --enable-static \ --disable-shared \ --cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \ --disable-doc \ --enable-postproc \ --enable-swscale \ --enable-avfilter \ --enable-avresample \ --disable-opencl \ --disable-securetransport \ --sysroot=$SYSROOT \ --enable-videotoolBox \ --enable-avresample \ --disable-symver \ #--enable-gpl \ #--enable-libx264 $ADDITIONAL_CONfigURE_FLAG make clean make -j9 make install } cpu=arm PREFIX=$(pwd)/android/$cpu ADDI_CFLAGS="-marm" build_ffmpeg_android
题:
我错过了哪个图书馆链接?
解决方法
c – 使用元编程来计算log2但是`编译终止’
#include <iostream> template <int i> struct power2 { enum { value = (1 << i) }; }; template <int n> class log2arr { int arr[n]; template <int i> struct log2 { log2<i - 1> _arr; enum { value = log2<i - 1>::value + (power2<log2<i - 1>::value>::value == i) }; void print() { _arr.print(); std::cout << value << std::endl; } void set() { _arr.set(); arr[i] = value; } }; template <> struct log2<1> { enum { value = 1 }; void print() {} void set() {} }; public: int *getArr() { log2<n>().set(); return arr; } }; int main() { log2arr<4> a = log2arr<4>(); for(auto i : a.getArr()){ cout << i; } }
但编译器只告诉我编译终止.
这是什么意思?我该如何解决?
任何帮助将不胜感激.
解决方法
(1)在struct / class中不允许完全特化;所以你不能在log2arr里面完全专门化log2.
你可以在log2arr之外迁移log2,或者,如果你真的希望将它保存在log2arr中,你可以在一个等价的部分特化中转换完全特化(在struct / class中合法);例如,如下
template <int I,typename = std::true_type> struct log2 { // body of the struct }; template <int I> struct log2<I,std::integral_constant<bool,I == 1>> { // body of the struct specialization };
(2)如果从getArr()返回一个int *,则会丢失有关log2Arr类中数组的信息;所以不适用于基于循环的范围(for(auto i:a.getArr())).
不幸的是你不能返回一个C风格的数组(你不能返回arr本身).
但是你使用的是C 11或更新版本(你只标记C但是你使用的是基于范围的循环,所以你至少使用C 11)所以我强烈建议你将arr定义为std :: array< int,N>,而不是C风格的数组(不是int arr [N]).我强烈建议你返回一个arr本身的引用(你可以使用std :: array)
private: using arrT = std::array<int,N>; arrT arr {}; // ... public: arrT & getArr () { /* ... */ return arr; }
我还建议为const对象添加一个getArr()
arrT const & getArr () const { /* ... */ return arr; }
(3)你不能在嵌入式结构log2的方法里面管理arr数组(不是log2Arr的静态成员)
void set() { _arr.set(); arr[i] = value; // <--- arr is inaccessible }
一个可能的解决方案是传递arr作为参考,所以
void set (arrT & a) // arrT = std::array<int,N> { _arr.set(a); a[i] = value; }
和(在log2< 1>中)
void set (arrT &) {}
显然你必须调用set()传递arr作为参数,所以
log2<N>().set(arr)
(4)在getArr()内部初始化arr是一个坏主意(恕我直言),因为每次调用getArr()时都会初始化arr.
而且:你不能在另一个方法中使用arr(如果你想添加另一个方法)而不在另一个方法中初始化它.
建议:在显式的构造函数中初始化arr,一次性.通过例子
log2arr () { log2<N>().set(arr); }
所以你的getArr()方法就变成了
arrT & getArr () { return arr; } arrT const & getArr () const { return arr; }
(5)log2< I>初始化arr [I]并记录< 1>没有初始化,你的int arr [N]包含未被初始化的arr [0]和arr [1]值.
您可以将这些值初始化为零写入
int arr[N] {};
或(使用std :: array< int,N>)
using arrT = std::array<int,N>; arrT arr {}; // ^^ <--- initialize all to zero
但你必须决定如何在arr [0]和arr [1]中初始化
(6)没有需要初始化如下
log2arr<4> a = log2arr<4>();
你可以简单地写
log2arr<4> a;
—————————————
以下是修改后的代码
#include <array> #include <iostream> template <int I> struct power2 { enum { value = (1 << I) }; }; template <int N> class log2arr { private: using arrT = std::array<int,N>; arrT arr {}; template <int I,typename = std::true_type> struct log2 { log2<I-1> _arr; enum { value = log2<I-1>::value + (power2<log2<I-1>::value>::value == I) }; void print () { _arr.print(); std::cout << value << std::endl; } void set (arrT & a) { _arr.set(a); a[I] = value; } }; template <int I> struct log2<I,I == 1>> { enum { value = 1 }; void print() {} void set(arrT &) {} }; public: log2arr () { log2<N>().set(arr); } arrT & getArr () { return arr; } arrT const & getArr () const { return arr; } }; int main () { log2arr<4> a; for ( auto i : a.getArr() ) std::cout << i; std::cout << std::endl; }
Log4j怎么改可以让日志文件按时期分开存放,如:serverLog2015-03-24.log, serverLog2015-03-25.log
-
log4j.rootLogger=info, rongFile
log4j.appender.rongFile = org.apache.log4j.DailyRollingFileAppender
log4j.appender.rongFile = org.apache.log4j.FileAppender
log4j.appender.rongFile = org.apache.log4j.RollingFileAppender
log4j.appender.rongFile.DatePattern = ''.''yyyy-MM-dd=ooo
log4j.appender.rongFile.File = /disk2/tomcat_log/serverLog.log
log4j.appender.rongFile.layout = org.apache.log4j.PatternLayout
log4j.appender.rongFile.MaxFileSize = 10MB
log4j.appender.rongFile.layout.ConversionPattern = %d - %m%n
log4j.appender.rongFile.MaxBackupIndex = 100
log4j.appender.rongFile.Append = truelog4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %d{yyyy-MM-dd HH\:mm\:ss} %p [%c] %m%n
lua学习笔记之一(C/C++程序员的Lua快速入门[初阶话题])
总结
以上是小编为你收集整理的lua学习笔记之一(C/C++程序员的Lua快速入门[初阶话题])全部内容。
如果觉得小编网站内容还不错,欢迎将小编网站推荐给好友。
我们今天的关于Lua快速计算log2和lua log函数的分享已经告一段落,感谢您的关注,如果您想了解更多关于Android FFmpeg:对atof,log2和log2f的未定义引用、c – 使用元编程来计算log2但是`编译终止’、Log4j怎么改可以让日志文件按时期分开存放,如:serverLog2015-03-24.log, serverLog2015-03-25.log、lua学习笔记之一(C/C++程序员的Lua快速入门[初阶话题])的相关信息,请在本站查询。
本文标签: